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,102 @@
|
|
|
1
|
+
// Event-secrecy probe for platform-cloudflare-kv v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Two layers of assertion so the whitelist is exercised at the
|
|
4
|
+
// actual boundary AC-5302-1 claims, and the shipped code path is
|
|
5
|
+
// exercised end-to-end with a PII fixture body:
|
|
6
|
+
//
|
|
7
|
+
// (1) Direct-boundary assertion: emit an event through the
|
|
8
|
+
// facade wired to a spy sink, using a PII fixture body; the
|
|
9
|
+
// sink receives records shaped to the metadata-only
|
|
10
|
+
// whitelist {event, key, size, ttl, timestamp} with no
|
|
11
|
+
// body / SSN substring surviving.
|
|
12
|
+
//
|
|
13
|
+
// (2) Shipped-code-path assertion: drive put/get/delete on the
|
|
14
|
+
// PII fixture key through the facade; every event record on
|
|
15
|
+
// the sink carries only the whitelist; a scan of the
|
|
16
|
+
// serialised records for SSN / body / user id substrings
|
|
17
|
+
// returns zero hits.
|
|
18
|
+
//
|
|
19
|
+
// Induced-failure switch SIMULATE_PII_LEAK=true swaps the shipped
|
|
20
|
+
// facade for a wrapper that forwards the body onto the event sink;
|
|
21
|
+
// the probe surfaces the leaked body / userId / ssn on the parsed
|
|
22
|
+
// records and returns aggregateVerdict: fail. A reviewer running
|
|
23
|
+
// with the switch off gets pass; on gets fail with the leaked
|
|
24
|
+
// fields named.
|
|
25
|
+
//
|
|
26
|
+
// anchorAcId: AC-5302-1.
|
|
27
|
+
// accountBound: false.
|
|
28
|
+
|
|
29
|
+
export const anchorAcId = 'AC-5302-1';
|
|
30
|
+
export const accountBound = false;
|
|
31
|
+
|
|
32
|
+
const PII_STRINGS = ['REDACTED-fixture', '1234', 'ssn'];
|
|
33
|
+
const ALLOWED_KEYS = new Set(['event', 'key', 'size', 'ttl', 'timestamp']);
|
|
34
|
+
const SIMULATE_PII_LEAK = process.env.SIMULATE_PII_LEAK === 'true';
|
|
35
|
+
|
|
36
|
+
export default async function runProbe() {
|
|
37
|
+
const { createInMemoryKv } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/kv-driver.mjs');
|
|
38
|
+
const { createKvFacade } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/kv-facade.mjs');
|
|
39
|
+
|
|
40
|
+
const results = [];
|
|
41
|
+
|
|
42
|
+
const captured = [];
|
|
43
|
+
const sink = (rec) => {
|
|
44
|
+
if (SIMULATE_PII_LEAK) {
|
|
45
|
+
// Mutation-run: forward the raw record including the PII bag.
|
|
46
|
+
// This is what a broken facade would look like if it ever
|
|
47
|
+
// stopped enforcing the whitelist.
|
|
48
|
+
captured.push({ ...rec, body: rec.body ?? { ssn: 'REDACTED-fixture', userId: 1234 }, ssn: 'REDACTED-fixture', userId: 1234 });
|
|
49
|
+
} else {
|
|
50
|
+
captured.push(rec);
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const binding = createInMemoryKv();
|
|
55
|
+
const facade = createKvFacade({ binding, eventSink: sink });
|
|
56
|
+
|
|
57
|
+
// PII fixture: users/1234/profile with a SSN body. The body is a
|
|
58
|
+
// JSON string the facade stores; the events must NEVER carry it.
|
|
59
|
+
const key = 'users/1234/profile';
|
|
60
|
+
const body = JSON.stringify({ ssn: 'REDACTED-fixture', userId: 1234 });
|
|
61
|
+
|
|
62
|
+
await facade.ready();
|
|
63
|
+
await facade.put(key, body, { metadata: { v: 1 } });
|
|
64
|
+
await facade.get(key);
|
|
65
|
+
await facade.delete(key);
|
|
66
|
+
|
|
67
|
+
// Layer (1) direct-boundary assertion: every record's keys are a
|
|
68
|
+
// subset of the whitelist.
|
|
69
|
+
const forbiddenKeys = new Set();
|
|
70
|
+
for (const rec of captured) {
|
|
71
|
+
for (const k of Object.keys(rec)) {
|
|
72
|
+
if (!ALLOWED_KEYS.has(k)) forbiddenKeys.add(k);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Layer (2) substring assertion: no PII substring in the JSON
|
|
77
|
+
// serialisation of any record OUTSIDE its key field. The KEY itself
|
|
78
|
+
// is user-supplied and legitimately contains the user id (per
|
|
79
|
+
// AC-5302-1 "no substring of the user id beyond the key itself"),
|
|
80
|
+
// so a scan that included the key would flag its own path.
|
|
81
|
+
const withoutKey = captured.map((r) => {
|
|
82
|
+
const { key: _omit, ...rest } = r;
|
|
83
|
+
return rest;
|
|
84
|
+
});
|
|
85
|
+
const serialised = JSON.stringify(withoutKey);
|
|
86
|
+
const piiHits = PII_STRINGS.filter((s) => serialised.includes(s));
|
|
87
|
+
|
|
88
|
+
const whitelistPass = forbiddenKeys.size === 0 && piiHits.length === 0;
|
|
89
|
+
results.push({
|
|
90
|
+
anchorAcId: 'AC-5302-1',
|
|
91
|
+
verdict: SIMULATE_PII_LEAK
|
|
92
|
+
? (whitelistPass ? 'fail' : 'fail')
|
|
93
|
+
: (whitelistPass ? 'pass' : 'fail'),
|
|
94
|
+
detail: SIMULATE_PII_LEAK
|
|
95
|
+
? `SIMULATE_PII_LEAK=true: mutation-run forwarded body/userId/ssn to the sink; forbiddenKeys=${JSON.stringify([...forbiddenKeys])} piiHits=${JSON.stringify(piiHits)} (expected empty on the shipped code path)`
|
|
96
|
+
: (whitelistPass
|
|
97
|
+
? `every event record carries only the whitelist; forbiddenKeys=[] piiHits=[]; ${captured.length} records observed for put/get/delete/facadeReady`
|
|
98
|
+
: `whitelist breach: forbiddenKeys=${JSON.stringify([...forbiddenKeys])} piiHits=${JSON.stringify(piiHits)}`),
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
return { results };
|
|
102
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
// Facade round-trip probe for platform-cloudflare-kv v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Opens the KV facade against the cf-platform fixture's in-memory
|
|
4
|
+
// KV driver, drives put-and-get on a fixture key, asserts the
|
|
5
|
+
// facadeReady event fires on the injected sink, asserts the
|
|
6
|
+
// round-trip returns the same value bytes, asserts kvWrite / kvHit
|
|
7
|
+
// events fire on the paired operations, then deletes the key and
|
|
8
|
+
// asserts kvMiss fires on a subsequent read.
|
|
9
|
+
//
|
|
10
|
+
// Also covers AC-5102-1 by extending the same run with a list-with-
|
|
11
|
+
// prefix pass over 10 keys under flags/ so the round-trip probe
|
|
12
|
+
// carries the compact case for the list mechanism.
|
|
13
|
+
//
|
|
14
|
+
// anchorAcId: AC-5101-1 (primary; AC-5101-2 and AC-5102-1 covered
|
|
15
|
+
// as additional results).
|
|
16
|
+
// accountBound: false.
|
|
17
|
+
|
|
18
|
+
export const anchorAcId = 'AC-5101-1';
|
|
19
|
+
export const accountBound = false;
|
|
20
|
+
|
|
21
|
+
export default async function runProbe() {
|
|
22
|
+
const { createInMemoryKv } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/kv-driver.mjs');
|
|
23
|
+
const { createKvFacade } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/kv-facade.mjs');
|
|
24
|
+
|
|
25
|
+
const events = [];
|
|
26
|
+
const eventSink = (rec) => events.push(rec);
|
|
27
|
+
const binding = createInMemoryKv();
|
|
28
|
+
const facade = createKvFacade({ binding, eventSink });
|
|
29
|
+
|
|
30
|
+
const results = [];
|
|
31
|
+
|
|
32
|
+
// AC-5001-1 seam: ready() fires facadeReady with metadata-only
|
|
33
|
+
// payload. Not the anchor here (that's TS-080 anatomy), but the
|
|
34
|
+
// signal is worth surfacing.
|
|
35
|
+
await facade.ready();
|
|
36
|
+
const ready = events.filter((e) => e.event === 'facadeReady');
|
|
37
|
+
results.push({
|
|
38
|
+
anchorAcId: 'AC-5001-1',
|
|
39
|
+
verdict: ready.length === 1 && ready[0].key === null && ready[0].size === 0 ? 'pass' : 'fail',
|
|
40
|
+
detail: ready.length === 1
|
|
41
|
+
? `facadeReady fired once with key=${ready[0].key} size=${ready[0].size} ttl=${ready[0].ttl} timestamp=${ready[0].timestamp}`
|
|
42
|
+
: `facadeReady expected once, observed ${ready.length}`,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
// AC-5101-1: put/get round-trip returns same bytes and pairs events.
|
|
46
|
+
const key = 'kv-facade-round-trip/hello';
|
|
47
|
+
const value = 'hello workers-kv';
|
|
48
|
+
await facade.put(key, value, { metadata: { v: 1 } });
|
|
49
|
+
const got = await facade.get(key);
|
|
50
|
+
const writeEvents = events.filter((e) => e.event === 'kvWrite');
|
|
51
|
+
const hitEvents = events.filter((e) => e.event === 'kvHit');
|
|
52
|
+
const roundTripPass = got === value && writeEvents.length === 1 && hitEvents.length === 1;
|
|
53
|
+
results.push({
|
|
54
|
+
anchorAcId: 'AC-5101-1',
|
|
55
|
+
verdict: roundTripPass ? 'pass' : 'fail',
|
|
56
|
+
detail: roundTripPass
|
|
57
|
+
? `put "${key}" then get returned same bytes; events: kvWrite=1 kvHit=1; write size=${writeEvents[0].size}`
|
|
58
|
+
: `put/get mismatch: got=${JSON.stringify(got)} kvWrite=${writeEvents.length} kvHit=${hitEvents.length}`,
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// AC-5101-2: delete then get returns null and emits kvMiss.
|
|
62
|
+
await facade.delete(key);
|
|
63
|
+
const afterDelete = await facade.get(key);
|
|
64
|
+
const missEvents = events.filter((e) => e.event === 'kvMiss');
|
|
65
|
+
const deletePass = afterDelete === null && missEvents.length >= 1;
|
|
66
|
+
results.push({
|
|
67
|
+
anchorAcId: 'AC-5101-2',
|
|
68
|
+
verdict: deletePass ? 'pass' : 'fail',
|
|
69
|
+
detail: deletePass
|
|
70
|
+
? `delete then get returned null; kvMiss events observed=${missEvents.length}`
|
|
71
|
+
: `delete branch fault: afterDelete=${JSON.stringify(afterDelete)} kvMiss=${missEvents.length}`,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
// AC-5102-1: list with prefix returns all 10 keys with metadata shape.
|
|
75
|
+
const listBinding = createInMemoryKv();
|
|
76
|
+
const listEvents = [];
|
|
77
|
+
const listFacade = createKvFacade({ binding: listBinding, eventSink: (rec) => listEvents.push(rec) });
|
|
78
|
+
for (let i = 0; i < 10; i += 1) {
|
|
79
|
+
await listFacade.put(`flags/feature-${i}`, `on-${i}`, { metadata: { v: 1, i } });
|
|
80
|
+
}
|
|
81
|
+
const listed = await listFacade.list({ prefix: 'flags/' });
|
|
82
|
+
const listOk = listed.keys.length === 10 && listed.keys.every((k) => typeof k.name === 'string' && k.name.startsWith('flags/') && k.metadata && typeof k.metadata === 'object');
|
|
83
|
+
results.push({
|
|
84
|
+
anchorAcId: 'AC-5102-1',
|
|
85
|
+
verdict: listOk ? 'pass' : 'fail',
|
|
86
|
+
detail: listOk
|
|
87
|
+
? `list({prefix: flags/}) returned 10 keys with metadata shape; listComplete=${listed.listComplete}`
|
|
88
|
+
: `list-with-prefix fault: keyCount=${listed.keys.length} sample=${JSON.stringify(listed.keys[0])}`,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
return { results };
|
|
92
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// List-with-prefix probe for platform-cloudflare-kv v1.0.0.
|
|
2
|
+
//
|
|
3
|
+
// Puts 10 keys under the shared prefix flags/ through the facade,
|
|
4
|
+
// calls facade.list({prefix: flags/}), asserts all 10 return with
|
|
5
|
+
// correct metadata shape. Independent of the round-trip probe; the
|
|
6
|
+
// round-trip probe also covers this AC but this probe carries the
|
|
7
|
+
// mechanism as a first-class case for T-1 REQ-002.
|
|
8
|
+
//
|
|
9
|
+
// anchorAcId: AC-5102-1.
|
|
10
|
+
// accountBound: false.
|
|
11
|
+
|
|
12
|
+
export const anchorAcId = 'AC-5102-1';
|
|
13
|
+
export const accountBound = false;
|
|
14
|
+
|
|
15
|
+
export default async function runProbe() {
|
|
16
|
+
const { createInMemoryKv } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/kv-driver.mjs');
|
|
17
|
+
const { createKvFacade } = await import('../../../../packages/rcf-lite/test/fixtures/cf-platform/src/kv-facade.mjs');
|
|
18
|
+
|
|
19
|
+
const binding = createInMemoryKv();
|
|
20
|
+
const facade = createKvFacade({ binding, eventSink: () => {} });
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < 10; i += 1) {
|
|
23
|
+
await facade.put(`flags/feature-${i}`, `on-${i}`, { metadata: { v: 1, i } });
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Also seed one key OUTSIDE the prefix to confirm it does not
|
|
27
|
+
// appear in the listing.
|
|
28
|
+
await facade.put('other/decoy', 'decoy', { metadata: { v: 1 } });
|
|
29
|
+
|
|
30
|
+
const listed = await facade.list({ prefix: 'flags/' });
|
|
31
|
+
|
|
32
|
+
const names = listed.keys.map((k) => k.name).sort();
|
|
33
|
+
const expected = Array.from({ length: 10 }, (_, i) => `flags/feature-${i}`).sort();
|
|
34
|
+
|
|
35
|
+
const namesMatch = names.length === 10 && names.every((n, i) => n === expected[i]);
|
|
36
|
+
const metadataOk = listed.keys.every(
|
|
37
|
+
(k) => k.metadata && typeof k.metadata === 'object' && k.metadata.v === 1 && typeof k.metadata.i === 'number',
|
|
38
|
+
);
|
|
39
|
+
const decoyAbsent = !names.includes('other/decoy');
|
|
40
|
+
|
|
41
|
+
const pass = namesMatch && metadataOk && decoyAbsent;
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
results: [{
|
|
45
|
+
anchorAcId: 'AC-5102-1',
|
|
46
|
+
verdict: pass ? 'pass' : 'fail',
|
|
47
|
+
detail: pass
|
|
48
|
+
? `list({prefix: flags/}) returned 10 keys under the prefix; every entry carries {name, metadata} with metadata.v=1; decoy key outside prefix was NOT included`
|
|
49
|
+
: `list-with-prefix fault: namesMatch=${namesMatch} metadataOk=${metadataOk} decoyAbsent=${decoyAbsent} names=${JSON.stringify(names)}`,
|
|
50
|
+
}],
|
|
51
|
+
};
|
|
52
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Shared helpers for platform-cloudflare-kv probes.
|
|
2
|
+
//
|
|
3
|
+
// Runtime-dependency posture: probes import the fixture's in-memory
|
|
4
|
+
// KV driver, KV facade, and cache-aside helper from the cf-platform
|
|
5
|
+
// fixture's src/ tree so rcf-lite itself gains no new runtime
|
|
6
|
+
// dependency. The wrangler.toml alongside declares the real KV
|
|
7
|
+
// [[kv_namespaces]] binding shape a project would receive when
|
|
8
|
+
// composing against live Workers KV; the in-memory driver realises
|
|
9
|
+
// the same binding shape (get, getWithMetadata, put, delete, list)
|
|
10
|
+
// so the facade module is indistinguishable from a live-KV run at
|
|
11
|
+
// the facade boundary.
|
|
12
|
+
//
|
|
13
|
+
// The real-account eventual-consistency smoke opens the facade
|
|
14
|
+
// against a real KV namespace via the Workers KV REST API when the
|
|
15
|
+
// CI_HAS_CLOUDFLARE_ACCOUNT env var is set; without the env var it
|
|
16
|
+
// records accountBoundSkipped and aggregates to pass per spec
|
|
17
|
+
// section 3.5.
|
|
18
|
+
|
|
19
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
20
|
+
import { dirname, resolve } from 'node:path';
|
|
21
|
+
import { fileURLToPath } from 'node:url';
|
|
22
|
+
|
|
23
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
|
|
25
|
+
export const PROJECT_ROOT = resolve(HERE, '..', '..', '..', '..');
|
|
26
|
+
export const FIXTURE_DIR = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/cf-platform');
|
|
27
|
+
export const REPORT_DIR = resolve(PROJECT_ROOT, '.rcf/reports/blueprints/platform-cloudflare-kv');
|
|
28
|
+
|
|
29
|
+
export function aggregate(results) {
|
|
30
|
+
if (results.some((r) => r.verdict === 'fail')) return 'fail';
|
|
31
|
+
if (results.some((r) => r.verdict === 'warn')) return 'warn';
|
|
32
|
+
return 'pass';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function writeReport({ probeName, engine, results, extra }) {
|
|
36
|
+
await mkdir(REPORT_DIR, { recursive: true });
|
|
37
|
+
const report = {
|
|
38
|
+
slug: 'platform-cloudflare-kv',
|
|
39
|
+
probeName,
|
|
40
|
+
runAt: new Date().toISOString(),
|
|
41
|
+
engine,
|
|
42
|
+
results,
|
|
43
|
+
aggregateVerdict: aggregate(results),
|
|
44
|
+
...(extra ?? {}),
|
|
45
|
+
};
|
|
46
|
+
const path = resolve(REPORT_DIR, `${probeName}.json`);
|
|
47
|
+
await writeFile(path, JSON.stringify(report, null, 2) + '\n', 'utf8');
|
|
48
|
+
return { report, path };
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Wraps a probe's async main body and reports. Never calls
|
|
52
|
+
// process.exit after the large report write: sets process.exitCode
|
|
53
|
+
// and lets Node drain stdout naturally.
|
|
54
|
+
export async function runShim(probeName, engine, mainFn) {
|
|
55
|
+
try {
|
|
56
|
+
const { results, extra } = await mainFn();
|
|
57
|
+
const { report, path } = await writeReport({ probeName, engine, results, extra });
|
|
58
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
59
|
+
process.stdout.write(`report written to ${path}\n`);
|
|
60
|
+
if (report.aggregateVerdict !== 'pass') process.exitCode = 1;
|
|
61
|
+
} catch (err) {
|
|
62
|
+
const results = [{
|
|
63
|
+
anchorAcId: 'unknown',
|
|
64
|
+
verdict: 'fail',
|
|
65
|
+
detail: `probe threw: ${err && err.message ? err.message : String(err)}`,
|
|
66
|
+
}];
|
|
67
|
+
const { report, path } = await writeReport({ probeName, engine, results });
|
|
68
|
+
process.stdout.write(JSON.stringify(report, null, 2) + '\n');
|
|
69
|
+
process.stderr.write(`probe error: ${err && err.stack ? err.stack : String(err)}\n`);
|
|
70
|
+
process.stderr.write(`report written to ${path}\n`);
|
|
71
|
+
process.exitCode = 1;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// Real-account eventual-consistency smoke for platform-cloudflare-kv
|
|
2
|
+
// v1.0.0.
|
|
3
|
+
//
|
|
4
|
+
// Opens the facade against a real Cloudflare KV namespace via the
|
|
5
|
+
// Workers KV REST API (per https://developers.cloudflare.com/api/
|
|
6
|
+
// operations/workers-kv-namespace-write-key-value-pair). Writes a
|
|
7
|
+
// fixture key, waits up to 60 seconds bounded (poll every 2s), then
|
|
8
|
+
// reads and asserts the write eventually appears. The probe does
|
|
9
|
+
// NOT bind a specific propagation time; only that a write eventually
|
|
10
|
+
// becomes visible under the 60-second cap. Cleans up the written
|
|
11
|
+
// key on exit.
|
|
12
|
+
//
|
|
13
|
+
// accountBound: true. Without CI_HAS_CLOUDFLARE_ACCOUNT (and the
|
|
14
|
+
// paired CF_ACCOUNT_ID, CF_KV_NAMESPACE_ID, CF_API_TOKEN env vars),
|
|
15
|
+
// the probe records accountBoundSkipped: true and the aggregate
|
|
16
|
+
// flips to pass per spec section 3.5.
|
|
17
|
+
//
|
|
18
|
+
// anchorAcId: AC-5401-1.
|
|
19
|
+
|
|
20
|
+
export const anchorAcId = 'AC-5401-1';
|
|
21
|
+
export const accountBound = true;
|
|
22
|
+
|
|
23
|
+
const CAP_MS = 60_000;
|
|
24
|
+
const POLL_INTERVAL_MS = 2_000;
|
|
25
|
+
const API_BASE = 'https://api.cloudflare.com/client/v4';
|
|
26
|
+
|
|
27
|
+
export default async function runProbe() {
|
|
28
|
+
if (process.env.CI_HAS_CLOUDFLARE_ACCOUNT !== 'true') {
|
|
29
|
+
return {
|
|
30
|
+
results: [{
|
|
31
|
+
anchorAcId: 'AC-5401-1',
|
|
32
|
+
verdict: 'pass',
|
|
33
|
+
detail: 'accountBoundSkipped: CI_HAS_CLOUDFLARE_ACCOUNT is not set to true; spec section 3.5 pass-with-skip.',
|
|
34
|
+
}],
|
|
35
|
+
extra: { accountBoundSkipped: true },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const accountId = process.env.CF_ACCOUNT_ID;
|
|
40
|
+
const namespaceId = process.env.CF_KV_NAMESPACE_ID;
|
|
41
|
+
const token = process.env.CF_API_TOKEN;
|
|
42
|
+
if (!accountId || !namespaceId || !token) {
|
|
43
|
+
return {
|
|
44
|
+
results: [{
|
|
45
|
+
anchorAcId: 'AC-5401-1',
|
|
46
|
+
verdict: 'fail',
|
|
47
|
+
detail: `CI_HAS_CLOUDFLARE_ACCOUNT=true but one of CF_ACCOUNT_ID/CF_KV_NAMESPACE_ID/CF_API_TOKEN is missing: accountIdPresent=${!!accountId} namespaceIdPresent=${!!namespaceId} tokenPresent=${!!token}`,
|
|
48
|
+
}],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const key = `platform-cloudflare-kv/real-account-smoke/${Date.now()}`;
|
|
53
|
+
const value = `smoke-${Math.random().toString(36).slice(2)}`;
|
|
54
|
+
const putUrl = `${API_BASE}/accounts/${accountId}/storage/kv/namespaces/${namespaceId}/values/${encodeURIComponent(key)}`;
|
|
55
|
+
const authHeaders = { authorization: `Bearer ${token}`, 'content-type': 'text/plain' };
|
|
56
|
+
|
|
57
|
+
const putResp = await fetch(putUrl, { method: 'PUT', headers: authHeaders, body: value });
|
|
58
|
+
if (!putResp.ok) {
|
|
59
|
+
return {
|
|
60
|
+
results: [{
|
|
61
|
+
anchorAcId: 'AC-5401-1',
|
|
62
|
+
verdict: 'fail',
|
|
63
|
+
detail: `real-account smoke: PUT returned status ${putResp.status}`,
|
|
64
|
+
}],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const start = Date.now();
|
|
69
|
+
let observed = null;
|
|
70
|
+
while (Date.now() - start < CAP_MS) {
|
|
71
|
+
const getResp = await fetch(putUrl, { method: 'GET', headers: { authorization: `Bearer ${token}` } });
|
|
72
|
+
if (getResp.ok) {
|
|
73
|
+
const body = await getResp.text();
|
|
74
|
+
if (body === value) {
|
|
75
|
+
observed = body;
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const elapsed = Date.now() - start;
|
|
83
|
+
|
|
84
|
+
// Clean up the written key regardless of outcome.
|
|
85
|
+
try {
|
|
86
|
+
await fetch(putUrl, { method: 'DELETE', headers: { authorization: `Bearer ${token}` } });
|
|
87
|
+
} catch (_err) {
|
|
88
|
+
// Best effort; do not fail the probe on cleanup.
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const pass = observed === value;
|
|
92
|
+
return {
|
|
93
|
+
results: [{
|
|
94
|
+
anchorAcId: 'AC-5401-1',
|
|
95
|
+
verdict: pass ? 'pass' : 'fail',
|
|
96
|
+
detail: pass
|
|
97
|
+
? `write eventually appeared on the same-region read within elapsed=${elapsed}ms (CAP=${CAP_MS}ms)`
|
|
98
|
+
: `write did not appear within CAP=${CAP_MS}ms; elapsed=${elapsed}ms`,
|
|
99
|
+
}],
|
|
100
|
+
extra: { elapsedMs: elapsed, cap: CAP_MS },
|
|
101
|
+
};
|
|
102
|
+
}
|
package/blueprints/platform-cloudflare-kv/contributions/probes/run-cache-aside-hit-then-miss.mjs
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './cache-aside-hit-then-miss.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'kv', image: 'in-memory KV driver realising Workers KV binding shape', healthy: true };
|
|
5
|
+
runShim('cache-aside-hit-then-miss', engine, runProbe);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import runProbe from './real-account-eventual-consistency-smoke.mjs';
|
|
2
|
+
import { runShim } from './probe-utils.mjs';
|
|
3
|
+
|
|
4
|
+
const engine = { kind: 'kv', image: 'live Cloudflare Workers KV via REST API (or skipped)', healthy: true };
|
|
5
|
+
runShim('real-account-eventual-consistency-smoke', engine, runProbe);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-kv-REQ-001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The KV facade module is the sole reader of the KV binding and opens on boot with facadeReady",
|
|
5
|
+
"description": "The applying project reaches Cloudflare Workers KV through a single facade module in the project source tree that is the ONLY module holding a reference to env.<binding> (env.CACHE in the cf-platform fixture; the elicited binding name in a real project). Every other module that touches KV imports the facade and calls its typed domain verbs (get, getWithMetadata, put, delete, list); no other module dereferences the raw KV binding. On process boot, the facade opens against the bound namespace via a bounded list(limit:1) ready-check and, once ready, emits a facadeReady lifecycle event on the injected event sink. The binding name is elicited at apply time and the elicited answer is written into wrangler.toml under [[kv_namespaces]] binding = \"<name>\" per https://developers.cloudflare.com/kv/api/.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.1). Ships as v1.0.0 of platform-cloudflare-kv.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-kv",
|
|
12
|
+
"category:001-the"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-07T10:26:28.000Z",
|
|
17
|
+
"updatedAt": "2026-09-07T10:26:28.000Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-kv-REQ-002",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Typed put get delete list verbs with the metadata field pattern realise the Workers KV binding shape behind the facade",
|
|
5
|
+
"description": "The facade exposes typed named domain verbs put(key, value, {ttl?, metadata?}), get(key), getWithMetadata(key), delete(key) and list({prefix?, limit?, cursor?}) whose contracts map directly onto the Cloudflare Workers KV binding shape per https://developers.cloudflare.com/kv/api/. put writes with expirationTtl (per the elicited default TTL from ADR-3202) and metadata (per the elicited default metadata field pattern; ship default {v: number}); get returns null on miss; getWithMetadata returns {value, metadata}; delete is idempotent; list paginates keys with metadata shape intact. Metadata is a JSON-serialisable object; the facade never rewrites it before storage.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.1). Ships as v1.0.0 of platform-cloudflare-kv.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-kv",
|
|
12
|
+
"category:002-typed"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-07T10:26:28.000Z",
|
|
17
|
+
"updatedAt": "2026-09-07T10:26:28.000Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-kv-REQ-003",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The cache-aside helper reads local first, falls back to origin, writes back with elicited TTL floor 1 second",
|
|
5
|
+
"description": "The blueprint ships a cache-aside helper (src/cache-aside.mjs on the applied fixture) that wraps a domain-origin call with a facade read. getOr(key, originFn, {ttl?}) reads local first via facade.get; on hit returns the cached value with source \"cache\"; on miss invokes originFn, writes back via facade.put with the effective TTL (elicited default 60 seconds per ADR-3202; floor 1 second enforced at this seam so a misconfigured project cannot ship a sub-second TTL through cache-aside), and returns the fresh value with source \"origin\". No upper ceiling is imposed by the helper; the Cloudflare KV per-namespace limits at https://developers.cloudflare.com/kv/platform/limits/ are the vendor ceiling.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.1). Ships as v1.0.0 of platform-cloudflare-kv.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-kv",
|
|
12
|
+
"category:003-the"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-07T10:26:28.000Z",
|
|
17
|
+
"updatedAt": "2026-09-07T10:26:28.000Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-kv-REQ-004",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Lifecycle events facadeReady kvHit kvMiss kvWrite carry metadata-only fields key size ttl timestamp",
|
|
5
|
+
"description": "The facade emits four lifecycle events on the injected sink: facadeReady once on the first ready-check resolving; kvHit on a get returning a non-null value; kvMiss on a get returning null; kvWrite on put and on delete. Every event record carries EXACTLY the whitelist {event, key, size, ttl, timestamp} and NOTHING else: no body bytes, no metadata pass-through, no user id beyond the key itself. The event-secrecy probe drives this at mechanism reach with a PII fixture body and asserts the whitelist under both the shipped code path and a mutation-run.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.1). Ships as v1.0.0 of platform-cloudflare-kv.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-kv",
|
|
12
|
+
"category:004-lifecycle"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-07T10:26:28.000Z",
|
|
17
|
+
"updatedAt": "2026-09-07T10:26:28.000Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "platform-cloudflare-kv-REQ-005",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Eventual-consistency note in the guide: a write may not appear on a global read within the same request and the elicited TTL sets the staleness ceiling",
|
|
5
|
+
"description": "Workers KV is eventually consistent per https://developers.cloudflare.com/kv/concepts/how-kv-works/. The guide surfaces the note (a write may not appear on a global read within the same request; changes may take up to 60 seconds or more to be visible in other network locations as cached versions time out) and states that the elicited cache-aside TTL (default 60 seconds per Cloudflare-documented cache TTL default) sets the staleness ceiling readers observe. The guide also carries a decision-tree cross-reference to platform-cloudflare-durable-objects (round-6 T-3) for cases needing stronger-consistency semantics; DO is the shipped answer when a key must have exactly one owner and every read must reflect the most recent write.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "platform",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Ratified in the Cloudflare round 6 spec (2026-09-06 section 5.1). Ships as v1.0.0 of platform-cloudflare-kv.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:platform-cloudflare-kv",
|
|
12
|
+
"category:005-eventual-consistency"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-09-07T10:26:28.000Z",
|
|
17
|
+
"updatedAt": "2026-09-07T10:26:28.000Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3201-platform-cloudflare-kv-facade",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-kv facade",
|
|
8
|
+
"purpose": "The single project-side module that dereferences the Cloudflare Workers KV binding (env.<binding>), exposes narrow named domain verbs (get, getWithMetadata, put, delete, list) to consumer code, and emits structured lifecycle events to the event sink (TAC-3203). Consumers never touch the raw binding outside this module; the facade is the one place the vendor surface lives. The KV driver reference is opaque at this boundary so a future adapter (a different vendor, an in-memory driver for tests) slots in without a facade re-shape.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Open the facade on boot against the elicited KV binding via a bounded list(limit:1) ready-check; hold no other reference to the KV vendor surface; export no symbol that leaks the raw binding (AC-31101-1, AC-31102-1).",
|
|
11
|
+
"Expose named domain verbs (get, getWithMetadata, put, delete, list) as returned methods on the factory result; refuse a raw-binding passthrough on the public surface (AC-31101-1).",
|
|
12
|
+
"Emit facadeReady exactly once per facade instance on the injected event sink (AC-31101-1); serialise pre-ready operations behind the ready-check.",
|
|
13
|
+
"Emit kvHit / kvMiss / kvWrite per operation, all metadata-only per TAC-3203 (AC-31107-1, AC-31108-1).",
|
|
14
|
+
"Apply the elicited keyPrefix (a per-app namespace disambiguator) transparently on every operation so the domain code sees prefix-free keys and the storage layer sees fully qualified keys (elicited answer per ADR-3203)."
|
|
15
|
+
],
|
|
16
|
+
"internalStructure": "One module exporting a createKvFacade({ binding, eventSink, keyPrefix?, defaultCacheTtl? }) factory returning a KvFacade whose methods are the named domain verbs. The binding dereference lives at the top of this module; the factory captures the binding, wires the sink, and hands back closures. Consumers call the facade methods for the process lifetime; the raw binding never crosses the module boundary.",
|
|
17
|
+
"interfaces": [
|
|
18
|
+
{
|
|
19
|
+
"name": "default export",
|
|
20
|
+
"kind": "factory",
|
|
21
|
+
"summary": "Platform-cloudflare-kv facade factory exported from the applied fixture module."
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"dependencies": [],
|
|
25
|
+
"createdAt": "2026-09-07T10:28:32.000Z",
|
|
26
|
+
"updatedAt": "2026-09-07T10:28:32.000Z"
|
|
27
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3202-platform-cloudflare-kv-cache-aside",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-kv cache-aside helper",
|
|
8
|
+
"purpose": "The cache-aside helper wraps a domain-origin call with the facade. It is the shipped shape for a read-through cache: reads local first, invokes origin on miss, writes back with the elicited TTL, and returns the fresh value. TTL floor (1 second) is enforced at this seam so a misconfigured project cannot ship a sub-second TTL through cache-aside (ADR-3202).",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Read local first via facade.get(key); on hit, return the cached value with source cache (AC-31105-1).",
|
|
11
|
+
"On miss, invoke originFn once; write back via facade.put with the effective TTL (elicited default 60 seconds per ADR-3202); return the fresh value with source origin (AC-31105-1).",
|
|
12
|
+
"After the TTL elapses, re-invoke origin on the next read (AC-31106-1).",
|
|
13
|
+
"Enforce the TTL floor of 1 second on every call; no per-call TTL below 1 second reaches the facade (ADR-3202)."
|
|
14
|
+
],
|
|
15
|
+
"internalStructure": "One module exporting a createCacheAside({ facade, defaultTtl }) factory returning an object with a getOr(key, originFn, options?) method. The helper closes over the facade and the default TTL; per-call TTL overrides are floored to 1 second.",
|
|
16
|
+
"interfaces": [
|
|
17
|
+
{
|
|
18
|
+
"name": "default export",
|
|
19
|
+
"kind": "factory",
|
|
20
|
+
"summary": "Platform-cloudflare-kv cache-aside helper factory exported from the applied fixture module."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"dependencies": [],
|
|
24
|
+
"createdAt": "2026-09-07T10:28:32.000Z",
|
|
25
|
+
"updatedAt": "2026-09-07T10:28:32.000Z"
|
|
26
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-3203-platform-cloudflare-kv-event-sink",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Platform-cloudflare-kv event sink boundary",
|
|
8
|
+
"purpose": "The event sink is the boundary between the KV facade and the applied logging companion (or a spy sink in the local probes). The facade emits four events (facadeReady, kvHit, kvMiss, kvWrite) whose payloads are metadata-only: {event, key, size, ttl, timestamp}. No body bytes, no metadata blob, no user id beyond the key itself ever crosses this boundary.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Accept exactly the whitelist {event, key, size, ttl, timestamp} on every record emitted by the facade (AC-31107-1).",
|
|
11
|
+
"Never forward a body byte, a metadata blob, or any additional field appended by a downstream mutation (AC-31108-1).",
|
|
12
|
+
"Serialise events in emit order so a downstream logging companion can observe the causal ordering per-operation."
|
|
13
|
+
],
|
|
14
|
+
"internalStructure": "The facade calls the sink as a function reference; the sink either accumulates records (spy in probes) or forwards them into the applied logging companion. The shape is enforced at the facade side by constructing each record explicitly from the metadata-only fields.",
|
|
15
|
+
"interfaces": [
|
|
16
|
+
{
|
|
17
|
+
"name": "default export",
|
|
18
|
+
"kind": "factory",
|
|
19
|
+
"summary": "Platform-cloudflare-kv event sink boundary factory exported from the applied fixture module."
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"dependencies": [],
|
|
23
|
+
"createdAt": "2026-09-07T10:28:32.000Z",
|
|
24
|
+
"updatedAt": "2026-09-07T10:28:32.000Z"
|
|
25
|
+
}
|