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,105 @@
|
|
|
1
|
+
# jobs-background v1.0.0
|
|
2
|
+
|
|
3
|
+
Background-jobs discipline over an applied `queue` capability. Ships a job-definition contract, a POSIX-cron plus one-shot-delayed scheduler, a retry contract that inherits the applied queue's max-attempts ceiling, and a metadata-only run-log event stream at four moments. Composes on the T-5 capability-consumer mechanism from the visual round; refuses apply on a bare project with exit 3 and the stable message id `jobs-background-no-queue` per Baz decision 5 on the ratified round-5 spec.
|
|
4
|
+
|
|
5
|
+
## What this gives you
|
|
6
|
+
|
|
7
|
+
- A job-definition module shape you export from `./jobs/*.mjs`: `{ name, handler, inputSchema, retryPolicy, timeoutMs }`.
|
|
8
|
+
- A scheduler with POSIX cron and one-shot-delayed shapes, elicited across `inProcess` (a Node long-lived process), `workerCron` (Cloudflare Cron Triggers) and `external` (a Kubernetes CronJob, a systemd timer, GitHub Actions schedule). A `workflows` mode is reserved for the v1.1.0 minor per section 5.7 of the spec.
|
|
9
|
+
- A retry contract that inherits the applied queue's max-attempts ceiling (Cloudflare Queues at 100 per the T-3 messaging-queue-cloudflare ADR-3003) and expresses the elicited backoff shape (`exponential`, `constant`, `linear`).
|
|
10
|
+
- A metadata-only run-log at four moments (`jobScheduled`, `jobStarted`, `jobCompleted`, `jobFailed`). Record whitelist: `{ jobId, jobName, attempts, duration, timestamp }` plus optional `terminalErrorCode`. No job input, no handler output, no user id, no email, no SSN, ever.
|
|
11
|
+
- An operator-facing surface elicited across `cli`, `httpEndpoint`, or `none`. The blueprint ships the contract; the applying project builds the thin shim.
|
|
12
|
+
|
|
13
|
+
## The six REQs
|
|
14
|
+
|
|
15
|
+
| REQ | Contract |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `jobs-background-REQ-001` | Requires an applied `queue` capability; refuses apply on a bare project with exit 3 and the stable message id `jobs-background-no-queue`. |
|
|
18
|
+
| `jobs-background-REQ-002` | Job-definition contract: name, handler, input schema (opaque per project), retry policy, timeout. |
|
|
19
|
+
| `jobs-background-REQ-003` | Scheduler contract: POSIX cron string and one-shot delayed. |
|
|
20
|
+
| `jobs-background-REQ-004` | Retry contract: handler throws retryable error re-delivers via the applied queue; max-attempts elicited within the applied queue's own ceiling. |
|
|
21
|
+
| `jobs-background-REQ-005` | Job-run event log: `jobScheduled`, `jobStarted`, `jobCompleted`, `jobFailed`; metadata-only whitelist. |
|
|
22
|
+
| `jobs-background-REQ-006` | Operator-facing surface (elicited): `cli`, `httpEndpoint`, or `none`. |
|
|
23
|
+
|
|
24
|
+
## Capability composition
|
|
25
|
+
|
|
26
|
+
`requiresAppliedCapabilities` on `blueprint.json`:
|
|
27
|
+
|
|
28
|
+
```json
|
|
29
|
+
{
|
|
30
|
+
"capabilities": ["queue"],
|
|
31
|
+
"allowSkipFlag": "allow-no-queue-yet",
|
|
32
|
+
"refusalMessageId": "jobs-background-no-queue"
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Apply refuses on a bare project (no applied blueprint declares `capabilities: ["queue"]`) with exit 3 and the stable first-line tag `[jobs-background-no-queue]`. The refusal message explicitly names `messaging-queue-cloudflare` as the shipped provider and `--allow-no-queue-yet` as the override.
|
|
37
|
+
|
|
38
|
+
The `--allow-no-queue-yet` override records a note on the sidecar `rcf/blueprints/jobs-background.applied.json` (`notes: "no queue yet: applied under --allow-no-queue-yet; surfaces gated on queue will refuse at runtime until a queue blueprint is applied."`). Note: the spec section 5.4 prose reference to `manifest.blueprints[jobs-background].source.notes` is superseded by the shipped T-5 mechanism which writes the note on the sidecar because the applied-blueprint-record schema in rcf-schemas 0.6.1 is closed and cannot carry a `notes` field. `rcf define validate` reads the sidecar to flag surfaces that never activated.
|
|
39
|
+
|
|
40
|
+
## Scheduler mode ADR (ADR-3102)
|
|
41
|
+
|
|
42
|
+
Scheduler mode is elicited across three values at v1.0.0 and reserves a fourth for v1.1.0:
|
|
43
|
+
|
|
44
|
+
- `inProcess`: a long-lived Node process holding `setInterval` per cron string and `setTimeout` per one-shot delay. Fits Node-server deploys; unsuitable for Cloudflare Workers.
|
|
45
|
+
- `workerCron`: Cloudflare Cron Triggers wire the scheduled event to a Worker handler that publishes to the applied queue, per the Cloudflare Cron Triggers documentation. Cron-trigger semantics are per-cron-string on the Worker's wrangler config, not per-job-cron on the runtime; the guide names the alignment. Refuses `workerCron` when the applied queue has no cron surface.
|
|
46
|
+
- `external`: an external cron runner (Kubernetes CronJob, GitHub Actions schedule, systemd timer) invokes an operator surface with a fire-now command.
|
|
47
|
+
- Reserved `workflows` (v1.1.0): wraps the same job-definition contract with Cloudflare Workflows `step.do` orchestration per section 5.7 of the spec and the round-6 proposal decision (b). Adds one enum value at ADR-3102 and one section to the guide; no facade re-shape.
|
|
48
|
+
|
|
49
|
+
## Timeout ceiling (ADR-3104)
|
|
50
|
+
|
|
51
|
+
Default handler `timeoutMs` is 60000 (60 seconds); floor is 1000 (1 second); ceiling is bounded by the applied queue's consumer wall-clock. Cloudflare Queues caps consumer wall-clock at 15 minutes per the platform limits documentation; a job-definition module declaring a `timeoutMs` above the ceiling refuses at boot with a clear error naming the ceiling and the applied provider.
|
|
52
|
+
|
|
53
|
+
## Companions and capabilities
|
|
54
|
+
|
|
55
|
+
- `capabilities: ["backgroundJobs"]` (per section 6a of `packages/rcf-lite/docs/blueprint-authoring.md`; a consumer blueprint reads this capability to obtain the job-definition and scheduler surfaces at apply time).
|
|
56
|
+
- `providesRoles`: absent.
|
|
57
|
+
- `suggestedCompanions`:
|
|
58
|
+
- `logging`: every `jobStarted` / `jobCompleted` / `jobFailed` event writes through the applied logger; a logging companion supplies the factory.
|
|
59
|
+
- `errorHandling`: a `jobFailed` constructs an internal error record with the terminal error code and the correlation id; an error-handling companion supplies the record factory and the boundary.
|
|
60
|
+
|
|
61
|
+
## The five probes
|
|
62
|
+
|
|
63
|
+
Each probe module lives under `contributions/probes/` and exports the spec section 3.2 verdict envelope with an `anchorAcId` matching a contributed AC id on the blueprint. Each has a matching `run-<probe-name>.mjs` shim writing a per-blueprint report at `.rcf/reports/blueprints/jobs-background/<probe-name>.json` per spec section 3.4.
|
|
64
|
+
|
|
65
|
+
- `apply-time-refusal.mjs` (anchors `AC-jobs-requiresQueue`): invokes `rcf define blueprint add ./blueprints/jobs-background` against a bare Node scratch fixture with NO queue applied; asserts exit 3, greps stderr for the first-line tag `[jobs-background-no-queue]`, greps stderr for the explicit provider name `messaging-queue-cloudflare` and the override flag `--allow-no-queue-yet`. Q3 default per spec section 10: asserts BOTH exit code AND stable message id.
|
|
66
|
+
- `apply-time-override.mjs` (anchors `AC-jobs-overrideRecorded`): same bare scratch fixture, but with `--allow-no-queue-yet`; asserts exit 0 and the sidecar `rcf/blueprints/jobs-background.applied.json` records `slug: jobs-background`, `allowNoAuthYet: true`, `appliedCapabilities: []`, and a `notes` field containing `no queue yet` and `--allow-no-queue-yet` and `queue` (but not the auth or secrets-management family words).
|
|
67
|
+
- `fake-clock-cron.mjs` (anchors `AC-jobs-scheduledRunsOnCron`): with `messaging-queue-cloudflare` and `jobs-background` both applied on the shared sample-app fixture, drives the fixture's fake-clock scheduler through one POSIX cron minute for the refresh-cache job; asserts `jobStarted` fires within the elicited `fireToleranceMs` window (default 30000 ms) and `jobCompleted` fires within the elicited `timeoutMs` (10000 ms for refresh-cache).
|
|
68
|
+
- `retry-and-fail.mjs` (anchors `AC-jobs-retryOnHandlerFailure`): with `SIMULATE_HANDLER_THROW=true` on the fixture, schedules a send-welcome-email job (`maxAttempts: 3`), drives the queue through re-deliveries; asserts three `jobStarted` events fire with the same `jobId` and attempts counter 1, 2, 3, followed by a terminal `jobFailed` with a `terminalErrorCode`.
|
|
69
|
+
- `event-secrecy.mjs` (anchors `AC-jobs-eventSecrecy`): with `SIMULATE_PII_IN_JOB_INPUT=true` on the fixture, schedules a job with a PII fixture input `{ userId: 1234, ssn: "123-45-6789", email: "test@example.com" }`; drives to completion; asserts every event record carries only the whitelist `{ event, jobId, jobName, attempts, duration, timestamp }` (plus optional `terminalErrorCode`) and NO PII literal.
|
|
70
|
+
|
|
71
|
+
## Running the probes
|
|
72
|
+
|
|
73
|
+
The probes drive against the shared sample-app fixture at `packages/rcf-lite/test/fixtures/infra-s3-and-queue/` (extended with `jobs/`, `src/jobs-runtime.mjs`, `src/scheduler.mjs`, `src/job-run-log.mjs`). No Docker, no `wrangler dev` process required; the T-3 in-memory queue-driver seam is the shipped local seam per SDR-3-a.
|
|
74
|
+
|
|
75
|
+
Two-line boot for the two headline probes:
|
|
76
|
+
|
|
77
|
+
```sh
|
|
78
|
+
node ../../../../blueprints/jobs-background/contributions/probes/run-apply-time-refusal.mjs
|
|
79
|
+
node ../../../../blueprints/jobs-background/contributions/probes/run-fake-clock-cron.mjs
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
The remaining three shims (`run-apply-time-override.mjs`, `run-retry-and-fail.mjs`, `run-event-secrecy.mjs`) follow the same pattern.
|
|
83
|
+
|
|
84
|
+
## Elicited parameters
|
|
85
|
+
|
|
86
|
+
- `jobsDir` (default `./jobs/`).
|
|
87
|
+
- `defaultRetryPolicy` (`{ maxAttempts: 3, backoff: "exponential" }`).
|
|
88
|
+
- `defaultTimeoutMs` (60000).
|
|
89
|
+
- `schedulerMode` (`inProcess` | `workerCron` | `external`; reserved `workflows` at v1.1.0).
|
|
90
|
+
- `operatorSurface` (`cli` | `httpEndpoint` | `none`).
|
|
91
|
+
- `fireToleranceMs` (default 30000).
|
|
92
|
+
|
|
93
|
+
## Known limitations (per-AC mechanism-reach form, round-3 checklist 6.g)
|
|
94
|
+
|
|
95
|
+
- AC-jobs-requiresQueue: PROVEN via `apply-time-refusal.mjs` against a bare scratch project on the shipped head (exit code and message id assertions run in-process). No live-only gap.
|
|
96
|
+
- AC-jobs-overrideRecorded: PROVEN via `apply-time-override.mjs` on the shipped head (sidecar note grep asserts `no queue yet`, `--allow-no-queue-yet`, and family word `queue`). No live-only gap.
|
|
97
|
+
- AC-jobs-scheduledRunsOnCron: PROVEN via `fake-clock-cron.mjs` on the shipped head against the in-memory queue-driver seam plus the injected fake-clock scheduler seam. LIVE `wrangler dev` cron-trigger firing under `workerCron` scheduler mode is the HQ gate reviewer's follow-up run per SDR-3-a; the shipped local seam proves the scheduler and runtime dispatch chain without a Cloudflare Queues account.
|
|
98
|
+
- AC-jobs-retryOnHandlerFailure: PROVEN via `retry-and-fail.mjs` on the shipped head (three `jobStarted` records at attempts 1, 2, 3 followed by terminal `jobFailed`). The in-memory queue-driver's re-delivery loop matches Cloudflare Queues' retry semantics per T-3's opaque-adapter clause; a live-account run against Cloudflare Queues is the T-3 real-account concurrency smoke's territory, not T-4's.
|
|
99
|
+
- AC-jobs-eventSecrecy: PROVEN via `event-secrecy.mjs` on the shipped head (grep on the serialised run-log stream returns zero matches for every PII fixture literal). No live-only gap; the whitelist enforcement lives in code, not in a runtime environment.
|
|
100
|
+
- `workerCron` refuses on an applied queue with no cron surface: DOCUMENTED at ADR-3102 in this blueprint's contribution set; not exercised at v1.0.0 because the shipped provider (`messaging-queue-cloudflare` v1.0.0) does not itself claim a cron surface (the cron surface is Workers-side per Cloudflare Cron Triggers, not Queues-side). A follow-up train fires the refusal live once a `queue`-capability provider with a cron surface ships.
|
|
101
|
+
- Reserved v1.1.0 `workflows` scheduler mode: DOCUMENTED at ADR-3102; the `fake-clock-cron.mjs` probe grows a `workflows-scheduler` variant when the v1.1.0 minor lands per section 5.7 of the spec.
|
|
102
|
+
|
|
103
|
+
## Reserved v1.1.0 minor: Workflows adapter
|
|
104
|
+
|
|
105
|
+
The v1.1.0 minor adds a fourth `scheduler` value (`workflows`) at ADR-3102, wrapping the same job-definition contract with Cloudflare Workflows `step.do` orchestration per section 5.7 of the spec. No topic conflict (the `backgroundJobModel` topic answer stays retry-and-schedule), no facade re-shape. Adds one section to this guide.
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "jobs-background",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"category": "jobs",
|
|
5
|
+
"capabilities": [
|
|
6
|
+
"backgroundJobs"
|
|
7
|
+
],
|
|
8
|
+
"requiresAppliedCapabilities": {
|
|
9
|
+
"capabilities": [
|
|
10
|
+
"queue"
|
|
11
|
+
],
|
|
12
|
+
"allowSkipFlag": "allow-no-queue-yet",
|
|
13
|
+
"refusalMessageId": "jobs-background-no-queue"
|
|
14
|
+
},
|
|
15
|
+
"suggestedCompanions": [
|
|
16
|
+
{
|
|
17
|
+
"role": "logging",
|
|
18
|
+
"reason": "Every jobStarted / jobCompleted / jobFailed event writes through the applied logger; a logging companion supplies the factory."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"role": "errorHandling",
|
|
22
|
+
"reason": "A jobFailed constructs an internal error record with the terminal error code and the correlation id; an error-handling companion supplies the record factory and the boundary."
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"contributions": [
|
|
26
|
+
{
|
|
27
|
+
"id": "jobs-background-REQ-001",
|
|
28
|
+
"kind": "req",
|
|
29
|
+
"path": "requirements/jobs-background-req-001.json"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"id": "jobs-background-REQ-002",
|
|
33
|
+
"kind": "req",
|
|
34
|
+
"path": "requirements/jobs-background-req-002.json"
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": "jobs-background-REQ-003",
|
|
38
|
+
"kind": "req",
|
|
39
|
+
"path": "requirements/jobs-background-req-003.json"
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"id": "jobs-background-REQ-004",
|
|
43
|
+
"kind": "req",
|
|
44
|
+
"path": "requirements/jobs-background-req-004.json"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"id": "jobs-background-REQ-005",
|
|
48
|
+
"kind": "req",
|
|
49
|
+
"path": "requirements/jobs-background-req-005.json"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"id": "jobs-background-REQ-006",
|
|
53
|
+
"kind": "req",
|
|
54
|
+
"path": "requirements/jobs-background-req-006.json"
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"id": "jobs-background-US-30101",
|
|
58
|
+
"kind": "us",
|
|
59
|
+
"path": "user-stories/jobs-background-us-30101.json"
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
"id": "jobs-background-US-30102",
|
|
63
|
+
"kind": "us",
|
|
64
|
+
"path": "user-stories/jobs-background-us-30102.json"
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"id": "jobs-background-US-30103",
|
|
68
|
+
"kind": "us",
|
|
69
|
+
"path": "user-stories/jobs-background-us-30103.json"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "jobs-background-US-30104",
|
|
73
|
+
"kind": "us",
|
|
74
|
+
"path": "user-stories/jobs-background-us-30104.json"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "jobs-background-US-30105",
|
|
78
|
+
"kind": "us",
|
|
79
|
+
"path": "user-stories/jobs-background-us-30105.json"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "jobs-background-US-30106",
|
|
83
|
+
"kind": "us",
|
|
84
|
+
"path": "user-stories/jobs-background-us-30106.json"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"id": "jobs-background-US-30107",
|
|
88
|
+
"kind": "us",
|
|
89
|
+
"path": "user-stories/jobs-background-us-30107.json"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "jobs-background-US-30108",
|
|
93
|
+
"kind": "us",
|
|
94
|
+
"path": "user-stories/jobs-background-us-30108.json"
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"id": "jobs-background-US-30109",
|
|
98
|
+
"kind": "us",
|
|
99
|
+
"path": "user-stories/jobs-background-us-30109.json"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"id": "TAC-3101-jobs-background-job-definition",
|
|
103
|
+
"kind": "tac",
|
|
104
|
+
"path": "tacs/tac-3101-jobs-background-job-definition.json"
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
"id": "TAC-3102-jobs-background-scheduler",
|
|
108
|
+
"kind": "tac",
|
|
109
|
+
"path": "tacs/tac-3102-jobs-background-scheduler.json"
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
"id": "TAC-3103-jobs-background-run-log",
|
|
113
|
+
"kind": "tac",
|
|
114
|
+
"path": "tacs/tac-3103-jobs-background-run-log.json"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"id": "ADR-3101-jobs-background-model",
|
|
118
|
+
"kind": "adr",
|
|
119
|
+
"path": "adrs/adr-3101-jobs-background-model.json",
|
|
120
|
+
"scope": "global",
|
|
121
|
+
"topic": "backgroundJobModel",
|
|
122
|
+
"standardsTraceClause": "generic enterprise practice"
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
"id": "ADR-3102-jobs-background-scheduler-mode",
|
|
126
|
+
"kind": "adr",
|
|
127
|
+
"path": "adrs/adr-3102-jobs-background-scheduler-mode.json",
|
|
128
|
+
"recommendedDefault": true,
|
|
129
|
+
"elicited": true,
|
|
130
|
+
"standardsTraceClause": "Cloudflare Cron Triggers documented worker cron surface"
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
"id": "ADR-3103-jobs-background-requires-applied-capabilities",
|
|
134
|
+
"kind": "adr",
|
|
135
|
+
"path": "adrs/adr-3103-jobs-background-requires-applied-capabilities.json",
|
|
136
|
+
"recommendedDefault": true,
|
|
137
|
+
"elicited": false,
|
|
138
|
+
"standardsTraceClause": "visual round spec section 5.5.2 (the T-5 capability-consumer mechanism)"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"id": "ADR-3104-jobs-background-timeout-floor",
|
|
142
|
+
"kind": "adr",
|
|
143
|
+
"path": "adrs/adr-3104-jobs-background-timeout-floor.json",
|
|
144
|
+
"recommendedDefault": true,
|
|
145
|
+
"elicited": true,
|
|
146
|
+
"standardsTraceClause": "Cloudflare Queues consumer wall-clock ceiling per platform limits doc"
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3101-jobs-background-model",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"scope": "global",
|
|
8
|
+
"topic": "backgroundJobModel",
|
|
9
|
+
"title": "Background-job model: retry-and-schedule as the shipped shape (scope global, new topic backgroundJobModel)",
|
|
10
|
+
"context": "A background-job discipline ships one of several models at the shipped-shape boundary: retry-and-schedule (cron + one-shot delayed, per-message retry, terminal DLQ) as this blueprint ships; stateful-workflow (Temporal-shape or Airflow-shape durable execution with multi-step state); durable-execution (Cloudflare Workflows step.do orchestration). The retry-and-schedule model composes cleanly on an applied queue capability; a stateful-workflow sibling would own its own persistent state store and its own scheduling contract. jobs-background claims the backgroundJobModel topic at scope global so future stateful-workflow siblings (a Temporal-shape or Airflow-shape blueprint) surface a DELIBERATE conflict and the operator picks one per project via a project-level ADR.",
|
|
11
|
+
"decision": "The shipped v1.0.0 shape is retry-and-schedule. The scheduler contract (POSIX cron plus one-shot delayed per REQ-003) and the retry contract (per-message re-delivery within the applied queue's max-attempts ceiling per REQ-004) are the two axes; the run-log at four moments per REQ-005 is the observability surface. The backgroundJobModel topic scope is global on this blueprint; the topic string is backgroundJobModel (lower camel case, one concept per topic, no version suffix, per the round-2 rules-for-new-topics clause). The round-6 Workflows adapter (per spec section 5.7 and round-6 decision (b)) lives INSIDE this blueprint as a v1.1.0 minor scheduler-mode value (workflows) at ADR-3102, not as a sibling; the topic backgroundJobModel is NOT re-claimed by the workflows mode. A future stateful-workflow sibling (a Temporal-shape blueprint) claims backgroundJobModel with a different answer and forces a DELIBERATE conflict.",
|
|
12
|
+
"consequences": "The applying project gets a retry-and-schedule background-job surface with metadata-only observability. Standards trace clause: generic enterprise practice for the job-definition and scheduler contracts. Future stateful-workflow siblings (Temporal-shape, Airflow-shape) will surface DELIBERATE conflicts on this topic; the operator resolves by picking one background-job model per project via a project-level ADR. The round-6 Workflows minor bump inside jobs-background is NOT a sibling; it is an elicited scheduler-mode value at ADR-3102 that keeps the backgroundJobModel topic answer unchanged.",
|
|
13
|
+
"alternativesConsidered": [
|
|
14
|
+
{
|
|
15
|
+
"name": "Ship stateful-workflow as the v1.0.0 default",
|
|
16
|
+
"summary": "Ship a Temporal-shape durable execution model as the primary v1.0.0 background-job surface with multi-step state.",
|
|
17
|
+
"reasonNotChosen": "Temporal-shape workflows require a persistent state store the applying project has to host; the round-5 shipped shape targets a directed producer-to-consumer worklist behind an applied queue. Stateful-workflow is a future sibling on the same topic, not the v1.0.0 default."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"name": "Ship durable-execution (Cloudflare Workflows) as the v1.0.0 default",
|
|
21
|
+
"summary": "Ship Cloudflare Workflows step.do as the primary v1.0.0 scheduler.",
|
|
22
|
+
"reasonNotChosen": "Cloudflare Workflows is a Cloudflare-only orchestration; the round-5 shipped shape targets a portable retry-and-schedule model over an applied queue capability that any queue provider can supply. Workflows is a scheduler-mode alternative at ADR-3102 (reserved for v1.1.0), not a topic-claim alternative."
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"createdAt": "2026-09-06T20:30:00.000Z",
|
|
26
|
+
"updatedAt": "2026-09-06T20:30:00.000Z"
|
|
27
|
+
}
|
package/blueprints/jobs-background/contributions/adrs/adr-3102-jobs-background-scheduler-mode.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3102-jobs-background-scheduler-mode",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Scheduler mode elicited: inProcess, workerCron, external (workflows reserved for v1.1.0)",
|
|
8
|
+
"context": "The scheduler surface can be realised in three shipped shapes today and a fourth shipped shape at v1.1.0. inProcess: a long-lived Node process (setInterval per cron string, setTimeout per one-shot delay) publishing to the applied queue. workerCron: Cloudflare Cron Triggers wire the scheduled event to a Worker handler that publishes to the applied queue (see the Cloudflare Cron Triggers documentation as the vendor reference for the fields at Cron Triggers, worker-side scheduled handler surface). external: an external cron runner (a Kubernetes CronJob, a GitHub Actions schedule, a systemd timer) invokes an operator surface (or the Node process boot line) with a fire-now command. The v1.1.0 minor per section 5.7 of the spec adds a workflows value that wraps the job-definition contract inside Cloudflare Workflows step.do orchestration; the v1.0.0 facade keeps the mode ELICITED so the fourth enum value slots in without a facade re-shape.",
|
|
9
|
+
"decision": "The scheduler mode is elicited at apply time between inProcess, workerCron and external. The default recommendation (recommendedDefault: true, elicited: true) is inProcess for a Node long-lived server, workerCron for a Cloudflare Worker deploy, and external for a fleet of short-lived containers already carrying an external cron runner. When the applied queue provider has no cron surface at all (which Cloudflare Queues does not directly; the cron surface is on Cloudflare Workers, not on Queues), workerCron mode refuses at apply time and the guide names the alignment. The v1.1.0 minor bump adds a workflows value; the standardsTraceClause of the contribution entry cites the Cloudflare Cron Triggers documented worker cron surface.",
|
|
10
|
+
"consequences": "The applying project picks a scheduler mode per environment. Standards trace clause: Cloudflare Cron Triggers documented worker cron surface. workerCron mode inherits Cloudflare cron-trigger semantics (per-cron-string on the Worker's wrangler config, not per-job-cron on the runtime); the guide names this alignment. external mode carries no lock-in but shifts the schedule discipline into the external runner; the guide names the trade-off. The reserved v1.1.0 workflows value carries the durable-execution semantics per the round-6 Workflows adapter proposal.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Hard-code inProcess as the shipped v1.0.0 default with no elicit",
|
|
14
|
+
"summary": "Ship inProcess as the only supported scheduler mode at v1.0.0.",
|
|
15
|
+
"reasonNotChosen": "A Cloudflare Worker deploy has no long-lived setInterval; hard-coding inProcess would refuse composition on the applied deploy-cloudflare-workers target the shared fixture uses. The elicited mode makes the shipped facade portable across the Node long-lived and Worker-cron shapes."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Ship the reserved workflows mode at v1.0.0",
|
|
19
|
+
"summary": "Include the Cloudflare Workflows step.do orchestration inline in the v1.0.0 shipped shape.",
|
|
20
|
+
"reasonNotChosen": "The round-6 Workflows adapter is on Baz per section 5.7 of the spec; v1.0.0 keeps the mode ELICITED at three values and the v1.1.0 minor adds workflows as the fourth. No topic conflict, no facade re-shape."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-06T20:30:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T20:30:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3103-jobs-background-requires-applied-capabilities",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Requires capabilities: [queue] with allowSkipFlag allow-no-queue-yet and refusalMessageId jobs-background-no-queue",
|
|
8
|
+
"context": "jobs-background composes on an applied queue capability. Applying on a bare project (no queue provider applied) has two possible shapes: refuse-with-message (the T-5 capability-consumer mechanism, ratified for application-admin-console and object-storage-s3), or silently apply with a stub queue (which would leave the applying project with an unactivated job dispatch surface). Baz decision 5 (verbatim): jobs requires an applied queue and refuses on a bare project, with an override flag.",
|
|
9
|
+
"decision": "The blueprint declares requiresAppliedCapabilities { capabilities: [queue], allowSkipFlag: allow-no-queue-yet, refusalMessageId: jobs-background-no-queue }. The apply verb refuses with exit 3 and the first-line stderr tag [jobs-background-no-queue] when no applied blueprint declares capabilities: [queue]. The refusal message names the shipped provider messaging-queue-cloudflare and the override flag --allow-no-queue-yet explicitly per Q3 default. The override writes a sidecar note under the queue family on rcf/blueprints/jobs-background.applied.json so rcf define validate later flags surfaces that never activated. Because the applied-blueprint-record schema in rcf-schemas 0.6.1 is closed, the note lives on the sidecar (rcf/blueprints/<slug>.applied.json), not on manifest.blueprints[].source.notes; the shipped T-5 mechanism (T-2 precedent for object-storage-s3) is the source of truth for that placement.",
|
|
10
|
+
"consequences": "The applying project's apply-time behaviour is predictable: refuse on bare, override-with-note or apply-with-queue. Standards trace clause: visual round spec section 5.5.2 (the T-5 capability-consumer mechanism). Dashboards and lints bind to the stable message id jobs-background-no-queue. The queue-family family derivation in the sidecar-notes construction (packages/rcf-lite/src/blueprint/apply.js buildOverrideNote) is extended to detect queue from the flag name so the note reads 'no queue yet' (not 'no auth yet' or 'no secrets-management yet').",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Silently apply on a bare project with a stub queue",
|
|
14
|
+
"summary": "Ship a no-op in-memory queue as the default when no queue capability is applied.",
|
|
15
|
+
"reasonNotChosen": "A silent stub loses the observability the T-5 mechanism gives; a project would ship jobs against a no-op queue without realising it. Baz decision 5 (verbatim) forecloses this."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Refuse on a bare project without an override flag",
|
|
19
|
+
"summary": "Refuse composition and require the applied queue before any apply call succeeds.",
|
|
20
|
+
"reasonNotChosen": "The scaffolding case (a project mid-migration that wants the jobs surface staged before the queue provider is picked) needs a documented escape hatch; the sidecar note lets rcf define validate later flag the gap so the scaffolding stays honest."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-06T20:30:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T20:30:00.000Z"
|
|
25
|
+
}
|
package/blueprints/jobs-background/contributions/adrs/adr-3104-jobs-background-timeout-floor.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-3104-jobs-background-timeout-floor",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Handler timeout: default 60 seconds, floor 1 second, ceiling bounded by the applied queue's consumer wall-clock",
|
|
8
|
+
"context": "A background-job handler has a bounded wall-clock in the applied queue's consumer. Cloudflare Queues caps consumer wall-clock at 15 minutes (900 seconds) per the platform limits documentation; a handler that runs past that mark is force-killed by the platform regardless of what timeoutMs the job-definition module declared. The jobs runtime enforces its own timeoutMs on the handler and treats a timed-out handler as a retryable error (a jobStarted followed by a jobFailed with retryable code, and the applied queue re-delivers per the retry contract).",
|
|
9
|
+
"decision": "The default handler timeoutMs is 60000 (60 seconds); the floor is 1000 (1 second); the ceiling is elicited per applied queue provider. For Cloudflare Queues the ceiling is 900000 (15 minutes) per the platform limits documentation. Job-definition modules that declare a timeoutMs above the ceiling refuse at boot with a clear error naming the ceiling and the applied provider. The elicited timeoutMs on a job definition is applied within the ceiling.",
|
|
10
|
+
"consequences": "The applying project inherits a handler-timeout discipline that respects the applied queue's own wall-clock. Standards trace clause: Cloudflare Queues consumer wall-clock ceiling per platform limits doc. A handler that needs longer than the applied provider's ceiling is a shape mismatch; the answer is either to split the handler into a state-machine driven by re-enqueues, or (at v1.1.0) adopt the workflows scheduler mode which lifts the per-run wall-clock via durable execution.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Ship a fixed 5-minute default timeout with no elicit",
|
|
14
|
+
"summary": "Hard-code a 5-minute default timeout on every job definition.",
|
|
15
|
+
"reasonNotChosen": "A shipped default of 60 seconds forces the applying project to make timeout an explicit choice on any long-running handler, which is the right posture for a shipped facade. 60 seconds is a common-enough handler wall-clock that most simple handlers do not need to opt out."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Ceiling as a global constant per shipped provider",
|
|
19
|
+
"summary": "Bake the 15-minute Cloudflare Queues ceiling into the blueprint code.",
|
|
20
|
+
"reasonNotChosen": "The ceiling depends on the applied queue provider; a future messaging-queue-postgres sibling would carry a different consumer wall-clock. The elicited ceiling per provider keeps the answer where the transport authority lives."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-09-06T20:30:00.000Z",
|
|
24
|
+
"updatedAt": "2026-09-06T20:30:00.000Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apply-time override probe.
|
|
3
|
+
*
|
|
4
|
+
* Invokes rcf define blueprint add ./blueprints/jobs-background
|
|
5
|
+
* --allow-no-queue-yet on a fresh scratch project WITH NO applied queue
|
|
6
|
+
* provider. Asserts exit 0, asserts rcf/blueprints/jobs-background
|
|
7
|
+
* .applied.json exists with allowNoAuthYet true, appliedCapabilities [],
|
|
8
|
+
* and notes containing 'no queue yet' + '--allow-no-queue-yet' + 'queue'
|
|
9
|
+
* (but NOT 'no auth yet' nor 'no secrets-management yet').
|
|
10
|
+
*
|
|
11
|
+
* Anchors AC-jobs-overrideRecorded.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { spawn } from 'node:child_process';
|
|
15
|
+
import { mkdtemp, readFile, rm, stat } from 'node:fs/promises';
|
|
16
|
+
import { tmpdir } from 'node:os';
|
|
17
|
+
import { join, resolve, dirname } from 'node:path';
|
|
18
|
+
import { fileURLToPath } from 'node:url';
|
|
19
|
+
|
|
20
|
+
import { PROJECT_ROOT } from './probe-utils.mjs';
|
|
21
|
+
|
|
22
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
23
|
+
const BLUEPRINT_DIR = resolve(HERE, '..', '..');
|
|
24
|
+
const RCF_BIN = resolve(PROJECT_ROOT, 'packages/rcf-lite/bin/rcf.js');
|
|
25
|
+
|
|
26
|
+
function runNode(args, opts = {}) {
|
|
27
|
+
return new Promise((resolveP) => {
|
|
28
|
+
const child = spawn(process.execPath, args, { stdio: ['ignore', 'pipe', 'pipe'], ...opts });
|
|
29
|
+
let stdout = '';
|
|
30
|
+
let stderr = '';
|
|
31
|
+
child.stdout.on('data', (b) => { stdout += b.toString('utf8'); });
|
|
32
|
+
child.stderr.on('data', (b) => { stderr += b.toString('utf8'); });
|
|
33
|
+
child.on('close', (code) => resolveP({ code, stdout, stderr }));
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export default async function runProbe() {
|
|
38
|
+
const scratch = await mkdtemp(join(tmpdir(), 'jobs-bg-override-'));
|
|
39
|
+
try {
|
|
40
|
+
const init = await runNode([RCF_BIN, 'init'], { cwd: scratch });
|
|
41
|
+
if (init.code !== 0) {
|
|
42
|
+
return [{
|
|
43
|
+
anchorAcId: 'AC-jobs-overrideRecorded',
|
|
44
|
+
verdict: 'fail',
|
|
45
|
+
detail: `rcf init failed exit=${init.code} stderr=${init.stderr}`,
|
|
46
|
+
}];
|
|
47
|
+
}
|
|
48
|
+
const apply = await runNode(
|
|
49
|
+
[RCF_BIN, 'define', 'blueprint', 'add', BLUEPRINT_DIR, '--allow-no-queue-yet'],
|
|
50
|
+
{ cwd: scratch },
|
|
51
|
+
);
|
|
52
|
+
if (apply.code !== 0) {
|
|
53
|
+
return [{
|
|
54
|
+
anchorAcId: 'AC-jobs-overrideRecorded',
|
|
55
|
+
verdict: 'fail',
|
|
56
|
+
detail: `apply --allow-no-queue-yet expected exit 0; got exit=${apply.code} stderr=${apply.stderr}`,
|
|
57
|
+
}];
|
|
58
|
+
}
|
|
59
|
+
// Sidecar path.
|
|
60
|
+
const sidecarPath = join(scratch, 'rcf', 'blueprints', 'jobs-background.applied.json');
|
|
61
|
+
try { await stat(sidecarPath); } catch {
|
|
62
|
+
return [{
|
|
63
|
+
anchorAcId: 'AC-jobs-overrideRecorded',
|
|
64
|
+
verdict: 'fail',
|
|
65
|
+
detail: `sidecar ${sidecarPath} missing after --allow-no-queue-yet apply`,
|
|
66
|
+
}];
|
|
67
|
+
}
|
|
68
|
+
const doc = JSON.parse(await readFile(sidecarPath, 'utf8'));
|
|
69
|
+
const results = [];
|
|
70
|
+
const notes = typeof doc.notes === 'string' ? doc.notes : '';
|
|
71
|
+
const checks = {
|
|
72
|
+
slug: doc.slug === 'jobs-background',
|
|
73
|
+
allowNoAuthYet: doc.allowNoAuthYet === true,
|
|
74
|
+
appliedCapabilitiesEmpty: Array.isArray(doc.appliedCapabilities) && doc.appliedCapabilities.length === 0,
|
|
75
|
+
notesQueueFamily: notes.includes('no queue yet'),
|
|
76
|
+
notesOverrideFlag: notes.includes('--allow-no-queue-yet'),
|
|
77
|
+
notesNamesCapability: notes.includes('queue'),
|
|
78
|
+
notesNotAuthFamily: !notes.includes('no auth yet'),
|
|
79
|
+
notesNotSecretsFamily: !notes.includes('no secrets-management yet'),
|
|
80
|
+
};
|
|
81
|
+
const pass = Object.values(checks).every(Boolean);
|
|
82
|
+
results.push({
|
|
83
|
+
anchorAcId: 'AC-jobs-overrideRecorded',
|
|
84
|
+
verdict: pass ? 'pass' : 'fail',
|
|
85
|
+
detail: pass
|
|
86
|
+
? `exit=0; sidecar recorded slug=jobs-background allowNoAuthYet=true appliedCapabilities=[]; notes carry 'no queue yet' + '--allow-no-queue-yet' + 'queue' and none of the auth/secrets family words`
|
|
87
|
+
: `checks=${JSON.stringify(checks)}; notes='${notes}'`,
|
|
88
|
+
});
|
|
89
|
+
// Do NOT include the sidecarPath (a per-run tmp path) in the report;
|
|
90
|
+
// the sidecar contents (doc) is the load-bearing evidence.
|
|
91
|
+
return { results, extra: { sidecar: doc } };
|
|
92
|
+
} finally {
|
|
93
|
+
try { await rm(scratch, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Apply-time refusal probe.
|
|
3
|
+
*
|
|
4
|
+
* Invokes rcf define blueprint add ./blueprints/jobs-background on a
|
|
5
|
+
* fresh scratch project WITH NO applied queue provider. Asserts exit 3,
|
|
6
|
+
* greps stderr for [jobs-background-no-queue] tag on the first line,
|
|
7
|
+
* greps stderr for the explicit provider name messaging-queue-cloudflare,
|
|
8
|
+
* and greps stderr for the override flag --allow-no-queue-yet.
|
|
9
|
+
*
|
|
10
|
+
* Anchors AC-jobs-requiresQueue.
|
|
11
|
+
*
|
|
12
|
+
* Q3 default per spec section 10: asserts BOTH exit code AND stable
|
|
13
|
+
* message id.
|
|
14
|
+
*
|
|
15
|
+
* The bare scratch project is created under a scratch tmp directory
|
|
16
|
+
* (not committed). rcf-lite is invoked via its bin script.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { spawn } from 'node:child_process';
|
|
20
|
+
import { mkdtemp, rm } from 'node:fs/promises';
|
|
21
|
+
import { tmpdir } from 'node:os';
|
|
22
|
+
import { join, resolve, dirname } from 'node:path';
|
|
23
|
+
import { fileURLToPath } from 'node:url';
|
|
24
|
+
|
|
25
|
+
import { PROJECT_ROOT } from './probe-utils.mjs';
|
|
26
|
+
|
|
27
|
+
const HERE = dirname(fileURLToPath(import.meta.url));
|
|
28
|
+
const BLUEPRINT_DIR = resolve(HERE, '..', '..');
|
|
29
|
+
const RCF_BIN = resolve(PROJECT_ROOT, 'packages/rcf-lite/bin/rcf.js');
|
|
30
|
+
|
|
31
|
+
function runNode(args, opts = {}) {
|
|
32
|
+
return new Promise((resolveP) => {
|
|
33
|
+
const child = spawn(process.execPath, args, { stdio: ['ignore', 'pipe', 'pipe'], ...opts });
|
|
34
|
+
let stdout = '';
|
|
35
|
+
let stderr = '';
|
|
36
|
+
child.stdout.on('data', (b) => { stdout += b.toString('utf8'); });
|
|
37
|
+
child.stderr.on('data', (b) => { stderr += b.toString('utf8'); });
|
|
38
|
+
child.on('close', (code) => resolveP({ code, stdout, stderr }));
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export default async function runProbe() {
|
|
43
|
+
const scratch = await mkdtemp(join(tmpdir(), 'jobs-bg-refuse-'));
|
|
44
|
+
try {
|
|
45
|
+
// 1. Init a bare rcf project (no applied blueprints).
|
|
46
|
+
const init = await runNode([RCF_BIN, 'init'], { cwd: scratch });
|
|
47
|
+
if (init.code !== 0) {
|
|
48
|
+
return [{
|
|
49
|
+
anchorAcId: 'AC-jobs-requiresQueue',
|
|
50
|
+
verdict: 'fail',
|
|
51
|
+
detail: `rcf init failed exit=${init.code} stderr=${init.stderr}`,
|
|
52
|
+
}];
|
|
53
|
+
}
|
|
54
|
+
// 2. Attempt to apply jobs-background on the bare project.
|
|
55
|
+
const apply = await runNode(
|
|
56
|
+
[RCF_BIN, 'define', 'blueprint', 'add', BLUEPRINT_DIR],
|
|
57
|
+
{ cwd: scratch },
|
|
58
|
+
);
|
|
59
|
+
const results = [];
|
|
60
|
+
const firstLine = apply.stderr.split('\n')[0] ?? '';
|
|
61
|
+
const tagMatch = firstLine.includes('[jobs-background-no-queue]');
|
|
62
|
+
const providerMatch = apply.stderr.includes('messaging-queue-cloudflare');
|
|
63
|
+
const overrideMatch = apply.stderr.includes('--allow-no-queue-yet');
|
|
64
|
+
const codeMatch = apply.code === 3;
|
|
65
|
+
const pass = codeMatch && tagMatch && providerMatch && overrideMatch;
|
|
66
|
+
results.push({
|
|
67
|
+
anchorAcId: 'AC-jobs-requiresQueue',
|
|
68
|
+
verdict: pass ? 'pass' : 'fail',
|
|
69
|
+
detail: pass
|
|
70
|
+
? `exit=${apply.code}; stderr first line carries [jobs-background-no-queue] tag; stderr names messaging-queue-cloudflare; stderr names --allow-no-queue-yet`
|
|
71
|
+
: `expected exit=3 AND first-line tag [jobs-background-no-queue] AND messaging-queue-cloudflare AND --allow-no-queue-yet; got exit=${apply.code}; firstLine='${firstLine}'; tagMatch=${tagMatch}; providerMatch=${providerMatch}; overrideMatch=${overrideMatch}`,
|
|
72
|
+
});
|
|
73
|
+
// Do NOT include the scratch dir path in the committed report; it is
|
|
74
|
+
// a per-run tmp path and would leak the machine's tmp naming into the
|
|
75
|
+
// gate-time evidence file.
|
|
76
|
+
return { results, extra: { exitCode: apply.code, stderrFirstLine: firstLine } };
|
|
77
|
+
} finally {
|
|
78
|
+
// rm -rf the scratch dir (deletion discipline: literal absolute
|
|
79
|
+
// scratch path created this call).
|
|
80
|
+
try { await rm(scratch, { recursive: true, force: true }); } catch { /* ignore */ }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Event-secrecy probe.
|
|
3
|
+
*
|
|
4
|
+
* Schedules a job whose input carries a PII fixture body
|
|
5
|
+
* { userId: 1234, ssn: '123-45-6789', email: 'test@example.com' }.
|
|
6
|
+
* Drives the job through completion. Grep the serialised run-log event
|
|
7
|
+
* stream for every PII literal; asserts zero matches.
|
|
8
|
+
*
|
|
9
|
+
* Anchors AC-jobs-eventSecrecy.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { createQueuePair } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/queue-driver.mjs';
|
|
13
|
+
import { createProducer, queueConfigFromEnv } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/producer.mjs';
|
|
14
|
+
import { createRunLog } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/job-run-log.mjs';
|
|
15
|
+
import { loadJobs, createJobsRuntime } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/jobs-runtime.mjs';
|
|
16
|
+
import { createScheduler, createFakeClock } from '../../../../packages/rcf-lite/test/fixtures/infra-s3-and-queue/src/scheduler.mjs';
|
|
17
|
+
import { PROJECT_ROOT } from './probe-utils.mjs';
|
|
18
|
+
import { resolve } from 'node:path';
|
|
19
|
+
|
|
20
|
+
const PII_LITERALS = ['1234', '123-45-6789', 'test@example.com'];
|
|
21
|
+
const EVENT_WHITELIST = new Set(['event', 'jobId', 'jobName', 'attempts', 'duration', 'timestamp', 'terminalErrorCode']);
|
|
22
|
+
|
|
23
|
+
export default async function runProbe() {
|
|
24
|
+
const cfg = queueConfigFromEnv();
|
|
25
|
+
const pair = createQueuePair({ queueName: cfg.queueName, dlqName: cfg.dlqName, maxRetries: cfg.maxRetries });
|
|
26
|
+
const events = [];
|
|
27
|
+
const runLog = createRunLog({ upstream: (e) => events.push(e) });
|
|
28
|
+
const producer = createProducer({
|
|
29
|
+
binding: pair.producer,
|
|
30
|
+
queueName: cfg.queueName,
|
|
31
|
+
onEvent: () => {},
|
|
32
|
+
});
|
|
33
|
+
await producer.ready;
|
|
34
|
+
const jobsDir = resolve(PROJECT_ROOT, 'packages/rcf-lite/test/fixtures/infra-s3-and-queue/jobs');
|
|
35
|
+
const registry = await loadJobs(jobsDir);
|
|
36
|
+
const runtime = createJobsRuntime({
|
|
37
|
+
jobRegistry: registry,
|
|
38
|
+
runLog,
|
|
39
|
+
env: { SIMULATE_PII_IN_JOB_INPUT: 'true' },
|
|
40
|
+
});
|
|
41
|
+
const clock = createFakeClock(0);
|
|
42
|
+
const scheduler = createScheduler({ mode: 'inProcess', clock, publisher: producer, runLog });
|
|
43
|
+
scheduler.delayed({
|
|
44
|
+
jobName: 'send-welcome-email',
|
|
45
|
+
delayMs: 0,
|
|
46
|
+
input: { userId: 1234, ssn: '123-45-6789', email: 'test@example.com' },
|
|
47
|
+
});
|
|
48
|
+
clock.advance(1);
|
|
49
|
+
await scheduler.tick();
|
|
50
|
+
await runtime.drain({ driverState: pair.state, maxIterations: 8 });
|
|
51
|
+
const serialised = JSON.stringify(events);
|
|
52
|
+
const leaks = PII_LITERALS.filter((lit) => serialised.includes(lit));
|
|
53
|
+
const wrongKeys = new Set();
|
|
54
|
+
for (const ev of events) {
|
|
55
|
+
for (const k of Object.keys(ev)) {
|
|
56
|
+
if (!EVENT_WHITELIST.has(k)) wrongKeys.add(k);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const results = [];
|
|
60
|
+
const pass = leaks.length === 0 && wrongKeys.size === 0 && events.some((e) => e.event === 'jobCompleted');
|
|
61
|
+
results.push({
|
|
62
|
+
anchorAcId: 'AC-jobs-eventSecrecy',
|
|
63
|
+
verdict: pass ? 'pass' : 'fail',
|
|
64
|
+
detail: pass
|
|
65
|
+
? `no PII literal appears in the serialised run-log stream; every event carries only whitelisted keys ${JSON.stringify([...EVENT_WHITELIST])}; ${events.length} events recorded`
|
|
66
|
+
: `leaks=${JSON.stringify(leaks)}; wrongKeys=${JSON.stringify([...wrongKeys])}; events=${JSON.stringify(events)}`,
|
|
67
|
+
});
|
|
68
|
+
return { results, extra: { events, piiLiterals: PII_LITERALS } };
|
|
69
|
+
}
|