rcf-lite 0.11.0 → 0.13.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 +30 -0
- package/README.md +2 -0
- package/bin/view-supervisor-child.mjs +0 -0
- package/blueprints/application-api-rest/README.md +40 -0
- package/blueprints/application-api-rest/assets/middleware/auth-classes.md +45 -0
- package/blueprints/application-api-rest/assets/openapi/openapi-skeleton.yaml +322 -0
- package/blueprints/application-api-rest/assets/sample-data/sample-resources.json +53 -0
- package/blueprints/application-api-rest/assets/samples/request-response-pairs.md +204 -0
- package/blueprints/application-api-rest/blueprint.json +265 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-301-application-api-rest-error-envelope.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-302-application-api-rest-auth-model.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-303-application-api-rest-api-versioning.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-304-application-api-rest-logging.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-305-application-api-rest-pagination.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-306-application-api-rest-idempotency.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-307-application-api-rest-openapi-generation.json +25 -0
- package/blueprints/application-api-rest/contributions/adrs/adr-308-application-api-rest-rate-limiting.json +25 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-001.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-002.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-003.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-004.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-005.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-006.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-007.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-008.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-009.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-010.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-011.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-012.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-013.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-014.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-015.json +18 -0
- package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-016.json +18 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-301-application-api-rest-request-pipeline.json +48 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-302-application-api-rest-auth-middleware.json +41 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-303-application-api-rest-contract-surface.json +46 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-304-application-api-rest-resource-layer.json +46 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-305-application-api-rest-observability.json +40 -0
- package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +46 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2101.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2102.json +73 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2104.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2105.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2106.json +73 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2107.json +90 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +90 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2109.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2110.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2111.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2112.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2113.json +73 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2114.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2115.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2116.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2117.json +64 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2118.json +72 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2119.json +63 -0
- package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2120.json +73 -0
- package/blueprints/application-api-rest/docs/topics.md +46 -0
- package/blueprints/application-api-rest/guide/application-api-rest.md +41 -0
- package/blueprints/application-spa/README.md +90 -0
- package/blueprints/application-spa/assets/component-specs/actions-and-text-inputs.md +36 -0
- package/blueprints/application-spa/assets/component-specs/data-display.md +19 -0
- package/blueprints/application-spa/assets/component-specs/feedback-and-status.md +27 -0
- package/blueprints/application-spa/assets/component-specs/overlays.md +23 -0
- package/blueprints/application-spa/assets/component-specs/selection-controls.md +23 -0
- package/blueprints/application-spa/assets/sample-data/sample-entities.json +41 -0
- package/blueprints/application-spa/assets/tokens/design-tokens.json +140 -0
- package/blueprints/application-spa/assets/tokens/theme.css +169 -0
- package/blueprints/application-spa/assets/viewports.md +18 -0
- package/blueprints/application-spa/assets/wireframes/dashboard.md +48 -0
- package/blueprints/application-spa/assets/wireframes/detail.md +40 -0
- package/blueprints/application-spa/assets/wireframes/empty.md +31 -0
- package/blueprints/application-spa/assets/wireframes/error.md +46 -0
- package/blueprints/application-spa/assets/wireframes/form.md +50 -0
- package/blueprints/application-spa/assets/wireframes/list.md +45 -0
- package/blueprints/application-spa/assets/wireframes/session-expired.md +35 -0
- package/blueprints/application-spa/assets/wireframes/sign-in.md +41 -0
- package/blueprints/application-spa/assets/wireframes/sign-out.md +32 -0
- package/blueprints/application-spa/blueprint.json +387 -0
- package/blueprints/application-spa/contributions/adrs/adr-201-application-spa-routing.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-202-application-spa-theming.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-203-application-spa-client-state.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-204-application-spa-error-envelope.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-205-application-spa-auth-model.json +25 -0
- package/blueprints/application-spa/contributions/adrs/adr-206-application-spa-iconography.json +13 -0
- package/blueprints/application-spa/contributions/adrs/adr-207-application-spa-motion.json +13 -0
- package/blueprints/application-spa/contributions/adrs/adr-208-application-spa-i18n.json +13 -0
- package/blueprints/application-spa/contributions/adrs/adr-209-application-spa-telemetry-naming.json +13 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-001.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-002.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-003.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-004.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-005.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-006.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-007.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-008.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-009.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-010.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-011.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-012.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-013.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-014.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-015.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-016.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-017.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-018.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-019.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-020.json +18 -0
- package/blueprints/application-spa/contributions/requirements/application-spa-req-021.json +18 -0
- package/blueprints/application-spa/contributions/tacs/tac-201-application-spa-app-shell.json +45 -0
- package/blueprints/application-spa/contributions/tacs/tac-202-application-spa-theme-system.json +32 -0
- package/blueprints/application-spa/contributions/tacs/tac-203-application-spa-component-library.json +32 -0
- package/blueprints/application-spa/contributions/tacs/tac-204-application-spa-client-data-layer.json +27 -0
- package/blueprints/application-spa/contributions/tacs/tac-205-application-spa-forms-engine.json +27 -0
- package/blueprints/application-spa/contributions/tacs/tac-206-application-spa-telemetry.json +19 -0
- package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +57 -0
- package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +56 -0
- package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +61 -0
- package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +70 -0
- package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +70 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1101.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1102.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1103.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1104.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1105.json +69 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1106.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1107.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1108.json +90 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1109.json +90 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1110.json +100 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1111.json +90 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1112.json +81 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1113.json +82 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1114.json +60 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1115.json +73 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1116.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1117.json +73 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1118.json +54 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1119.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1120.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1121.json +73 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1122.json +69 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1123.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1124.json +60 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1125.json +69 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1126.json +78 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1127.json +63 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1128.json +51 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1129.json +54 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1130.json +54 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1132.json +72 -0
- package/blueprints/application-spa/contributions/user-stories/application-spa-us-1133.json +72 -0
- package/blueprints/application-spa/docs/topics.md +57 -0
- package/blueprints/application-spa/guide/application-spa.md +40 -0
- package/blueprints/ci-pipeline/README.md +49 -0
- package/blueprints/ci-pipeline/assets/ci-provider-examples/github-actions.yml +61 -0
- package/blueprints/ci-pipeline/assets/ci-provider-examples/notes.md +50 -0
- package/blueprints/ci-pipeline/assets/report-samples/per-gate.json +12 -0
- package/blueprints/ci-pipeline/assets/report-samples/pipeline.json +28 -0
- package/blueprints/ci-pipeline/blueprint.json +46 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-701-ci-pipeline-ci-gates.json +25 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-702-ci-pipeline-strict-coverage-gate.json +25 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-703-ci-pipeline-node-only-runner.json +25 -0
- package/blueprints/ci-pipeline/contributions/adrs/adr-704-ci-pipeline-report-shape.json +25 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-001.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-002.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-003.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-004.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-005.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-006.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-007.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-008.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-009.json +18 -0
- package/blueprints/ci-pipeline/contributions/requirements/ci-pipeline-req-010.json +18 -0
- package/blueprints/ci-pipeline/contributions/tacs/tac-701-ci-pipeline-gate-runner.json +59 -0
- package/blueprints/ci-pipeline/contributions/tacs/tac-702-ci-pipeline-gate-report.json +32 -0
- package/blueprints/ci-pipeline/contributions/tacs/tac-703-ci-pipeline-aggregate-report.json +41 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6101.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6102.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6103.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6104.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6105.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6106.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6107.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6108.json +37 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6109.json +36 -0
- package/blueprints/ci-pipeline/contributions/user-stories/ci-pipeline-us-6110.json +36 -0
- package/blueprints/ci-pipeline/docs/topics.md +49 -0
- package/blueprints/ci-pipeline/guide/ci-pipeline.md +79 -0
- package/blueprints/deploy-cloudflare-workers/README.md +63 -0
- package/blueprints/deploy-cloudflare-workers/assets/ci-workflows/build-and-upload.yml.md +109 -0
- package/blueprints/deploy-cloudflare-workers/assets/ci-workflows/promote.yml.md +120 -0
- package/blueprints/deploy-cloudflare-workers/assets/verification/served-surface-probes.md +90 -0
- package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/bootstrap-vs-steady-state.md +87 -0
- package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/preview-alias-shape.md +86 -0
- package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/wrangler-toml-shape.md +85 -0
- package/blueprints/deploy-cloudflare-workers/blueprint.json +48 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1301-deploy-cloudflare-workers-deployment-target.json +30 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1302-deploy-cloudflare-workers-default-vendor.json +35 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1303-deploy-cloudflare-workers-preview-vs-production.json +30 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1304-deploy-cloudflare-workers-rollback-is-promote.json +25 -0
- package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1305-deploy-cloudflare-workers-dev-mode-drift.json +25 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-001.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-002.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-003.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-004.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-005.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-006.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-007.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-008.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-009.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-010.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-011.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-012.json +18 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1301-deploy-cloudflare-workers-deploy-adapter.json +54 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1302-deploy-cloudflare-workers-wrangler-manifest.json +45 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1303-deploy-cloudflare-workers-preview-url-resolver.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1304-deploy-cloudflare-workers-promote-gate.json +57 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1305-deploy-cloudflare-workers-served-surface-verifier.json +51 -0
- package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1306-deploy-cloudflare-workers-deploy-ci-workflows.json +64 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12101.json +54 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12102.json +45 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12103.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12104.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12105.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12106.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12107.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12108.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12109.json +47 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12110.json +46 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12111.json +45 -0
- package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12112.json +46 -0
- package/blueprints/deploy-cloudflare-workers/docs/topics.md +46 -0
- package/blueprints/deploy-cloudflare-workers/guide/deploy-cloudflare-workers.md +74 -0
- package/blueprints/email-smtp-resend/README.md +45 -0
- package/blueprints/email-smtp-resend/assets/from-address-rotation-pattern.md +44 -0
- package/blueprints/email-smtp-resend/assets/resend-verification-pointer.md +25 -0
- package/blueprints/email-smtp-resend/assets/stub-adapter.md +65 -0
- package/blueprints/email-smtp-resend/blueprint.json +23 -0
- package/blueprints/email-smtp-resend/contributions/adrs/adr-401-email-smtp-resend-transport-choice.json +30 -0
- package/blueprints/email-smtp-resend/contributions/adrs/adr-402-email-smtp-resend-retry-and-backoff-posture.json +30 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-001.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-002.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-003.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-004.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-005.json +18 -0
- package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-006.json +18 -0
- package/blueprints/email-smtp-resend/contributions/tacs/tac-401-email-smtp-resend-send-adapter.json +53 -0
- package/blueprints/email-smtp-resend/contributions/tacs/tac-402-email-smtp-resend-webhook-verifier.json +56 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4101.json +45 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4102.json +36 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4103.json +45 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4104.json +45 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4105.json +36 -0
- package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4106.json +37 -0
- package/blueprints/email-smtp-resend/docs/topics.md +44 -0
- package/blueprints/email-smtp-resend/guide/email-smtp-resend.md +71 -0
- package/blueprints/observability-essentials/README.md +53 -0
- package/blueprints/observability-essentials/assets/probe-samples/liveness-body.json +4 -0
- package/blueprints/observability-essentials/assets/probe-samples/readiness-body.json +18 -0
- package/blueprints/observability-essentials/assets/status-page-samples/status-page-clean.html +22 -0
- package/blueprints/observability-essentials/assets/status-page-samples/status-page-with-notice.html +25 -0
- package/blueprints/observability-essentials/blueprint.json +54 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +30 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +30 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-803-observability-essentials-status-page-contract.json +30 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-804-observability-essentials-probe-secrecy.json +25 -0
- package/blueprints/observability-essentials/contributions/adrs/adr-805-observability-essentials-notification-outcome-model.json +25 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-003.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-004.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-005.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-006.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-007.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-008.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-009.json +18 -0
- package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-010.json +18 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +32 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +43 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-803-observability-essentials-status-page.json +37 -0
- package/blueprints/observability-essentials/contributions/tacs/tac-804-observability-essentials-notification-outcome.json +42 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7103.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7104.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7105.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7106.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7107.json +46 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7108.json +47 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7109.json +45 -0
- package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7110.json +46 -0
- package/blueprints/observability-essentials/docs/topics.md +57 -0
- package/blueprints/observability-essentials/guide/observability-essentials.md +68 -0
- package/blueprints/observability-probe-endpoints/README.md +53 -0
- package/blueprints/observability-probe-endpoints/assets/docker/dockerfile-healthcheck.md +19 -0
- package/blueprints/observability-probe-endpoints/assets/kubernetes/podspec-probes-separate-port.md +54 -0
- package/blueprints/observability-probe-endpoints/assets/kubernetes/podspec-probes.md +36 -0
- package/blueprints/observability-probe-endpoints/assets/load-balancer/health-check-config.md +23 -0
- package/blueprints/observability-probe-endpoints/assets/systemd/notify-service.md +30 -0
- package/blueprints/observability-probe-endpoints/assets/uptime-monitor/monitor-config.md +22 -0
- package/blueprints/observability-probe-endpoints/blueprint.json +44 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1501-observability-probe-endpoints-health-probes.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1502-observability-probe-endpoints-readiness-semantics.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1504-observability-probe-endpoints-separate-port-option.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1505-observability-probe-endpoints-external-response-secrecy.json +30 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-001.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-002.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-003.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-004.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-005.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-006.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-007.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-008.json +18 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1501-observability-probe-endpoints-profile-resolver.json +39 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1502-observability-probe-endpoints-handler-set.json +40 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1503-observability-probe-endpoints-listener-topology.json +51 -0
- package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json +39 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14101.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14103.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14104.json +45 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14105.json +46 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14106.json +45 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +45 -0
- package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14108.json +46 -0
- package/blueprints/observability-probe-endpoints/docs/topics.md +51 -0
- package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +83 -0
- package/blueprints/persistence-data-d1/README.md +50 -0
- package/blueprints/persistence-data-d1/assets/batch-usage/batch-atomicity-example.md +72 -0
- package/blueprints/persistence-data-d1/assets/facade-shape/facade-module-shape.md +115 -0
- package/blueprints/persistence-data-d1/assets/migration-shape/migration-file-shape.md +119 -0
- package/blueprints/persistence-data-d1/assets/wrangler-config/d1-binding-shape.md +93 -0
- package/blueprints/persistence-data-d1/blueprint.json +42 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1401-persistence-data-d1-store-model.json +30 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1402-persistence-data-d1-migration-discipline.json +30 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1403-persistence-data-d1-event-secrecy.json +25 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1404-persistence-data-d1-store-boundary.json +25 -0
- package/blueprints/persistence-data-d1/contributions/adrs/adr-1405-persistence-data-d1-recovery-model.json +30 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-001.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-002.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-003.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-004.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-005.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-006.json +18 -0
- package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-007.json +18 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1401-persistence-data-d1-facade.json +51 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1402-persistence-data-d1-migration-catalog.json +31 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1403-persistence-data-d1-deploy-gate.json +38 -0
- package/blueprints/persistence-data-d1/contributions/tacs/tac-1404-persistence-data-d1-recovery-runner.json +39 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13101.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13102.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13103.json +46 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13104.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13105.json +45 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13106.json +46 -0
- package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13107.json +38 -0
- package/blueprints/persistence-data-d1/docs/topics.md +59 -0
- package/blueprints/persistence-data-d1/guide/persistence-data-d1.md +77 -0
- package/blueprints/persistence-data-sqlite/README.md +50 -0
- package/blueprints/persistence-data-sqlite/assets/backup-procedures/hot-checkpoint-note.md +22 -0
- package/blueprints/persistence-data-sqlite/assets/backup-procedures/sqlite-file-copy.md +70 -0
- package/blueprints/persistence-data-sqlite/assets/schema-samples/catalog-file-layout.md +73 -0
- package/blueprints/persistence-data-sqlite/assets/schema-samples/migration-shape.md +76 -0
- package/blueprints/persistence-data-sqlite/blueprint.json +50 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-601-persistence-data-sqlite-store-model.json +30 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-602-persistence-data-sqlite-migration-discipline.json +30 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-603-persistence-data-sqlite-event-secrecy.json +25 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-604-persistence-data-sqlite-store-boundary.json +25 -0
- package/blueprints/persistence-data-sqlite/contributions/adrs/adr-605-persistence-data-sqlite-backup-model.json +25 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-001.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-002.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-003.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-004.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-005.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-006.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-007.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-008.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-009.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-010.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-011.json +18 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-601-persistence-data-sqlite-store.json +57 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-602-persistence-data-sqlite-migration-runner.json +34 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-603-persistence-data-sqlite-migration-catalog.json +31 -0
- package/blueprints/persistence-data-sqlite/contributions/tacs/tac-604-persistence-data-sqlite-backup-runner.json +33 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5101.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5102.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5103.json +37 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5104.json +45 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5105.json +45 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5106.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5107.json +45 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5108.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5109.json +46 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5110.json +37 -0
- package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5111.json +37 -0
- package/blueprints/persistence-data-sqlite/docs/topics.md +49 -0
- package/blueprints/persistence-data-sqlite/guide/persistence-data-sqlite.md +69 -0
- package/blueprints/security-auth-clerk/README.md +50 -0
- package/blueprints/security-auth-clerk/assets/authorisation/role-claim-mapping-sample.md +99 -0
- package/blueprints/security-auth-clerk/assets/middleware/node-middleware-shape.md +86 -0
- package/blueprints/security-auth-clerk/assets/wiring/clerk-provider-react.md +48 -0
- package/blueprints/security-auth-clerk/assets/wiring/clerk-provider-vue.md +41 -0
- package/blueprints/security-auth-clerk/blueprint.json +42 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1001-security-auth-clerk-auth-model.json +30 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1002-security-auth-clerk-middleware-boundary.json +25 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1003-security-auth-clerk-authorisation-adapter-contract.json +25 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1004-security-auth-clerk-claims-mapping-discipline.json +25 -0
- package/blueprints/security-auth-clerk/contributions/adrs/adr-1005-security-auth-clerk-session-lifecycle.json +25 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-001.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-002.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-003.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-004.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-005.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-006.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-007.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-008.json +18 -0
- package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-009.json +18 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1001-security-auth-clerk-middleware.json +42 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1002-security-auth-clerk-authorisation-adapter.json +30 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1003-security-auth-clerk-session-verifier.json +38 -0
- package/blueprints/security-auth-clerk/contributions/tacs/tac-1004-security-auth-clerk-claims-mapper.json +22 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9101.json +46 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9102.json +38 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9103.json +46 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9104.json +46 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9105.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9106.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9107.json +37 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9108.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9109.json +36 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9110.json +37 -0
- package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9111.json +36 -0
- package/blueprints/security-auth-clerk/docs/topics.md +56 -0
- package/blueprints/security-auth-clerk/guide/security-auth-clerk.md +71 -0
- package/blueprints/security-auth-keycloak/README.md +56 -0
- package/blueprints/security-auth-keycloak/assets/local-container/keycloak-bootstrap.md +54 -0
- package/blueprints/security-auth-keycloak/assets/middleware/verifier-wiring.md +93 -0
- package/blueprints/security-auth-keycloak/assets/mock-introspection/mock-introspection-shape.md +62 -0
- package/blueprints/security-auth-keycloak/assets/provider-router/router-shape.md +71 -0
- package/blueprints/security-auth-keycloak/assets/realm-skeleton/realm-config-shape.md +55 -0
- package/blueprints/security-auth-keycloak/blueprint.json +49 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1201-security-auth-keycloak-auth-model.json +35 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1202-security-auth-keycloak-verification-mode-choice.json +30 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1203-security-auth-keycloak-provider-routing-seam.json +30 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1204-security-auth-keycloak-session-vs-token-contract.json +25 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1205-security-auth-keycloak-jwks-rotation-cache-lifetime.json +30 -0
- package/blueprints/security-auth-keycloak/contributions/adrs/adr-1206-security-auth-keycloak-refresh-and-sign-out-posture.json +25 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-001.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-002.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-003.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-004.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-005.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-006.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-007.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-008.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-009.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-010.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-011.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-012.json +18 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1201-security-auth-keycloak-discovery-client.json +51 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1202-security-auth-keycloak-jwt-verifier.json +46 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1203-security-auth-keycloak-introspection-client.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1204-security-auth-keycloak-provider-router.json +37 -0
- package/blueprints/security-auth-keycloak/contributions/tacs/tac-1205-security-auth-keycloak-role-adapter.json +32 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11101.json +47 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11102.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11103.json +36 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11104.json +36 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11105.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11106.json +46 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11107.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11108.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11109.json +37 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11110.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11111.json +45 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11112.json +37 -0
- package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11113.json +36 -0
- package/blueprints/security-auth-keycloak/docs/topics.md +74 -0
- package/blueprints/security-auth-keycloak/guide/security-auth-keycloak.md +81 -0
- package/blueprints/security-auth-magic-link/README.md +46 -0
- package/blueprints/security-auth-magic-link/assets/email-templates/magic-link-email.md +44 -0
- package/blueprints/security-auth-magic-link/assets/email-templates/stub-adapter.md +55 -0
- package/blueprints/security-auth-magic-link/assets/principal-registry-samples/allow-list-file.md +46 -0
- package/blueprints/security-auth-magic-link/assets/principal-registry-samples/single-address.md +35 -0
- package/blueprints/security-auth-magic-link/blueprint.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-501-security-auth-magic-link-model.json +30 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-502-security-auth-magic-link-token-secrecy.json +25 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-503-security-auth-magic-link-anti-enumeration-budget.json +25 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-504-security-auth-magic-link-session-lifecycle.json +30 -0
- package/blueprints/security-auth-magic-link/contributions/adrs/adr-505-security-auth-magic-link-rate-limiting.json +25 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-001.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-002.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-003.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-004.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-005.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-006.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-007.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-008.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-009.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-010.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-011.json +18 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-501-security-auth-magic-link-manager.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-502-security-auth-magic-link-session-manager.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-503-security-auth-magic-link-login-routes.json +76 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-504-security-auth-magic-link-email-delivery-adapter.json +26 -0
- package/blueprints/security-auth-magic-link/contributions/tacs/tac-505-security-auth-magic-link-principal-registry.json +26 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3101.json +64 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3102.json +54 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3103.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3104.json +55 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3105.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3106.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3107.json +54 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3108.json +46 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3109.json +48 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3110.json +45 -0
- package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3111.json +45 -0
- package/blueprints/security-auth-magic-link/docs/topics.md +45 -0
- package/blueprints/security-auth-magic-link/guide/security-auth-magic-link.md +65 -0
- package/blueprints/security-auth-oauth2/README.md +50 -0
- package/blueprints/security-auth-oauth2/assets/mock-provider/mock-oidc-shape.md +55 -0
- package/blueprints/security-auth-oauth2/assets/provider-selector/list-shape.md +27 -0
- package/blueprints/security-auth-oauth2/assets/providers/generic-oidc-discovery.md +31 -0
- package/blueprints/security-auth-oauth2/assets/providers/github-oauth2-only.md +31 -0
- package/blueprints/security-auth-oauth2/assets/providers/google-oidc.md +31 -0
- package/blueprints/security-auth-oauth2/assets/session-bridge/opaque-handle-shape.md +59 -0
- package/blueprints/security-auth-oauth2/blueprint.json +44 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1101-security-auth-oauth2-auth-model.json +35 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1102-security-auth-oauth2-provider-abstraction-contract.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1103-security-auth-oauth2-pkce-discipline.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1104-security-auth-oauth2-session-bridge-shape.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1105-security-auth-oauth2-refresh-token-posture.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/adrs/adr-1106-security-auth-oauth2-multi-provider-routing.json +25 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-001.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-002.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-003.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-004.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-005.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-006.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-007.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-008.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-009.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-010.json +18 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1101-security-auth-oauth2-flow-controller.json +61 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1102-security-auth-oauth2-provider-adapter.json +33 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1103-security-auth-oauth2-session-bridge.json +51 -0
- package/blueprints/security-auth-oauth2/contributions/tacs/tac-1104-security-auth-oauth2-provider-selector.json +29 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10101.json +47 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10102.json +45 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10103.json +36 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10104.json +36 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10105.json +55 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10106.json +45 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10107.json +46 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10108.json +46 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10109.json +37 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10110.json +37 -0
- package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10111.json +28 -0
- package/blueprints/security-auth-oauth2/docs/topics.md +58 -0
- package/blueprints/security-auth-oauth2/guide/security-auth-oauth2.md +65 -0
- package/blueprints/security-secrets-management/README.md +48 -0
- package/blueprints/security-secrets-management/assets/cli-usage/agent-access-pattern.md +69 -0
- package/blueprints/security-secrets-management/assets/manifest-samples/environment-aware-example.md +33 -0
- package/blueprints/security-secrets-management/assets/manifest-samples/secrets-yaml-shape.md +74 -0
- package/blueprints/security-secrets-management/assets/ui-integration/three-way-choice.md +44 -0
- package/blueprints/security-secrets-management/blueprint.json +43 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-901-security-secrets-management-secrets-source.json +30 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-902-security-secrets-management-default-vendor.json +35 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-903-security-secrets-management-agent-access-discipline.json +25 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-904-security-secrets-management-dotenv-reflection.json +25 -0
- package/blueprints/security-secrets-management/contributions/adrs/adr-905-security-secrets-management-rotation-and-audit.json +30 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-001.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-002.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-003.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-004.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-005.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-006.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-007.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-008.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-009.json +18 -0
- package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-010.json +18 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-901-security-secrets-management-manager-client.json +52 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-902-security-secrets-management-manifest.json +34 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-903-security-secrets-management-env-reflector.json +46 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-904-security-secrets-management-rotation-gate.json +57 -0
- package/blueprints/security-secrets-management/contributions/tacs/tac-905-security-secrets-management-agent-cli.json +59 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8101.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8102.json +45 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8103.json +37 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8104.json +45 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8105.json +55 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8106.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8107.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8108.json +45 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8109.json +46 -0
- package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8110.json +45 -0
- package/blueprints/security-secrets-management/docs/topics.md +46 -0
- package/blueprints/security-secrets-management/guide/security-secrets-management.md +68 -0
- package/fixtures/canary-manifest.json +1 -101
- package/package.json +16 -10
- package/rcf/.identity/profile.md +37 -0
- package/rcf/knowledge/INDEX.md +12 -0
- package/rcf/knowledge/README.md +41 -0
- package/rcf/knowledge/docs/.gitkeep +0 -0
- package/rcf/knowledge/notes/.gitkeep +0 -0
- package/scripts/preinstall-node-check.mjs +61 -0
- package/src/blueprint/apply.js +12 -6
- package/src/blueprint/conflicts.js +8 -8
- package/src/blueprint/index.js +2 -1
- package/src/blueprint/list.js +60 -0
- package/src/blueprint/loader.js +26 -1
- package/src/blueprint/namespace.js +20 -16
- package/src/blueprint/shelf-resolver.js +173 -0
- package/src/blueprint/supersede.js +3 -2
- package/src/browser-verify/invariants.js +40 -0
- package/src/browser-verify/runner.js +2 -0
- package/src/cli/blueprint.js +53 -9
- package/src/cli/init.js +2 -0
- package/src/core/store/validator.js +15 -27
- package/src/core/store/writer.js +64 -2
- package/src/ruleset/ruleset.json +1 -1
- package/src/setup/agent-setup.js +28 -10
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-1303-deploy-cloudflare-workers-preview-vs-production",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Preview URLs (per-version-id + stable alias) and production URL are distinct addressable surfaces; the promote step is what changes which one production maps to",
|
|
8
|
+
"context": "The failure mode this ADR closes is the collapsed URL: a project where the reviewer of a merged change and the visitor to the deployed application look at the same URL. When the preview surface and the production surface are the same string, every merge is a production act, review is what happens after users notice, and rollback is a second merge landing before enough users notice. The vendor's own primitive shape supports keeping them distinct: every uploaded version has a permanent per-version-id URL and a mutable stable-alias URL that can be pointed at the newest-of-main; production is the mapped custom domain (or the workers.dev production host) whose current version id changes only on an explicit deploy verb.",
|
|
9
|
+
"decision": "The blueprint mandates three URL kinds per Worker, all distinct hostnames, all discoverable through the Deploy Adapter's `deploy status` verb: (1) a per-VERSION-ID URL, unique per upload, permanent, useful for pinning a change-review link; (2) a STABLE PREVIEW ALIAS URL fixed to an operator-chosen alias string (the common default is `main`), always resolving to the newest-of-main uploaded version, useful for a persistent stakeholder-shareable link; (3) a PRODUCTION URL, declared under the wrangler manifest's `route`/`routes`/`workers_dev`/custom-domain stanza, changing which version it maps to only when a `promote` workflow runs. The Preview URL Resolver (TAC-1303) assembles the first two and refuses any alias string whose assembled host segment equals the production URL's host segment. The manifest loader refuses a wrangler config whose production route resolves to the preview alias URL host with `DEPLOY_URL_COLLAPSED`.",
|
|
10
|
+
"consequences": "Reviewers and stakeholders reach the newest-of-main at a persistent, memorable URL that never masquerades as production. Users hit production at a hostname that only changes version behind an explicit operator act. Change-review links are pinnable to a specific version id and never rot. The trade is one Worker now surfaces three URLs the project has to reason about (and the operator has to explain once when a new engineer joins); the payoff is the class of leaks-through-collapsed-URL is closed by the manifest's own validation, not by discipline.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Preview alias URL and production URL as the same string with a query parameter switching mode",
|
|
14
|
+
"summary": "One hostname, `?preview=1` flips to the newest-of-main; production is the default response.",
|
|
15
|
+
"reasonNotChosen": "The query-parameter mode is trivially forgettable and does not survive a link-shortener, an email quoting, or a browser that strips query strings. The class of leak this ADR closes reopens exactly when the operator hands out the URL to someone who does not add the query parameter."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Per-version URLs only; no stable alias URL",
|
|
19
|
+
"summary": "Every upload gets a URL; the stable-shareable-review-URL story is 'copy the URL from the CI run'.",
|
|
20
|
+
"reasonNotChosen": "The per-version-id URL is essential for pinning a change; the stable alias URL is essential for a persistent 'the latest' surface stakeholders can bookmark. Shipping only the first fails the persistent-review use case; the vendor's own primitive supports both cheaply so both ship."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Preview URL = production URL under a special header",
|
|
24
|
+
"summary": "One hostname; the vendor routes to the newest-of-main when a specific request header is set (a signed cookie, an auth-only bypass).",
|
|
25
|
+
"reasonNotChosen": "Same class as the query-parameter option: the mode is invisible to the URL string and non-portable across link handoffs. It also couples the preview surface to an auth model that may not exist on day one."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
29
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
30
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-1304-deploy-cloudflare-workers-rollback-is-promote",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Rollback is a promote of a prior version id; the promote workflow is the sole ship-to-production path",
|
|
8
|
+
"context": "Rollback is one of the two shapes a project reaches for at exactly the wrong time to discover drift. The failure mode: a project ships a rollback verb once during setup, does not exercise it under pressure until an incident lands, then discovers the rollback path diverged from the ship path (a different vendor call, a different auth path, a different secret binding, a stale probe set, no served-surface verify). Framing rollback as a promote of a known-good version id keeps the audit shape uniform, the auth path identical, the probe set the same, and the served-surface verifier applied unconditionally.",
|
|
9
|
+
"decision": "Rolling production back to a previous version is not a distinct code path in the project. It is the same `promote` workflow triggered with the prior version id supplied as the `versionId` input. `listVersions` on the Deploy Adapter exposes the history with the currently-serving id marked so the operator can pick a known-good id. The deploy-log record for a rollback carries the same fields as any promote (`promotedVersionId`, `promotedBy`, `previousVersionId`, `promotedAt`). The vendor's own convenience verbs (a `wrangler rollback` shortcut when the default vendor is in play) are optional operator documentation; at the blueprint's contract level any such shortcut is a promote of a prior version id and the audit trail is identical. A project-authored `rollback` script that bypasses the Promote Gate, the deploy log, or the Served-surface Verifier is not permitted.",
|
|
10
|
+
"consequences": "One ship path serves every ship-to-production act: the merge-to-main promote, the hotfix promote of an out-of-sequence upload, the rollback promote of a prior version id. The audit trail is uniform; a query for 'every production change in the last week' answers the same way for a forward promote and a rollback. The trade: an operator responding to an incident with `wrangler rollback` at the command line (rather than through the `promote` workflow) bypasses the deploy-log record and the served-surface verifier; the blueprint documents this in the guide as a break-glass path that is not the recorded ship path.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Bespoke `rollback` workflow with its own trigger and its own vendor call",
|
|
14
|
+
"summary": "A `rollback` workflow file separate from `promote`; triggers on manual dispatch; calls `wrangler rollback` (or the vendor's rollback verb) directly.",
|
|
15
|
+
"reasonNotChosen": "Two ship paths is one too many. The bespoke workflow drifts from the promote path over time (different secret binding, different logging, different probe set) and the drift is invisible until an incident. Keeping rollback on the same path as promote closes the class."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Rollback as a git revert + normal promote of the reverted-merge upload",
|
|
19
|
+
"summary": "Rollback is not a distinct verb at all; the operator opens a revert PR, waits for the merge, waits for the `build-and-upload` run, then promotes the new upload.",
|
|
20
|
+
"reasonNotChosen": "The revert flow works for cases where the incident is not urgent and the correct answer is a proper revert. It fails the incident case where the fix is a known-good version id from thirty minutes ago that the operator wants serving now. The chosen model handles both cases on one path."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-1305-deploy-cloudflare-workers-dev-mode-drift",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Local dev-mode is an emulator; ship-gate coverage never counts a dev-mode probe as a deployed observation",
|
|
8
|
+
"context": "Every deploy vendor of any complexity ships a local development mode: a process that runs on the developer's laptop and answers requests at a loopback port, approximating the deployed runtime. The failure mode is the emulator being treated as authoritative for ship coverage: an AC scoped `deployed` gets a test case that hits the dev-mode URL and passes there because the emulator handles the case, then fails on production because the emulator's regular-expression engine differs, or its static-assets ordering differs, or its binding-emulation surface differs. The RCF `deployed` scope tag exists precisely to close this class; the blueprint has to make the class refuseable at the coverage-gate layer.",
|
|
9
|
+
"decision": "The blueprint's `deployed`-scope ACs are only satisfied by a probe against an actual uploaded Worker: a per-version-id URL, a preview alias URL, or the production URL. A test case whose runtime target URL matches the dev-mode local pattern (`http://localhost:*`, `http://127.0.0.1:*`, or the vendor's local emulator loopback host) is refused as coverage for a `deployed`-scope AC with the code `DEPLOY_DEV_MODE_INADMISSIBLE`. Dev-mode remains a valid target for `runtime`-scope and `library`-scope ACs, and for developer-loop iteration; it is inadmissible for `deployed`-scope coverage. The project's runtime-verify catalogue names the dev-mode drift classes the operator authoring probes must be aware of; the catalogue is kept current against the vendor's release notes.",
|
|
10
|
+
"consequences": "The ship gate refuses a class of easy-to-hit false positives that would otherwise let a passing local test carry a broken deployed AC to green. The trade: some kinds of probe (a startup-behaviour probe, a code-shape probe) that would run cheaply against dev-mode now cost a full upload-plus-preview to satisfy the deployed-scope AC; the blueprint's guide names those as the classes the operator authors as `runtime`-scope ACs against dev-mode where the deployed observation adds no signal, and as `deployed`-scope ACs against the preview URL where it does.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Treat dev-mode as fully-authoritative when a project-declared fidelity flag is set",
|
|
14
|
+
"summary": "The project declares 'dev-mode is close enough for our purposes' and the coverage gate accepts dev-mode probes for deployed-scope ACs.",
|
|
15
|
+
"reasonNotChosen": "The flag becomes an escape hatch that quietly disables the gate the RCF `deployed` scope tag exists to enforce. When the emulator drifts in a way the project does not yet know about, the flag masks it. If a project genuinely wants dev-mode as its runtime target, it authors those ACs as `runtime`-scope and does not need the flag."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Warn on dev-mode probes for deployed-scope ACs; do not refuse",
|
|
19
|
+
"summary": "The coverage gate emits a warning and counts the coverage anyway.",
|
|
20
|
+
"reasonNotChosen": "Warnings that do not refuse become noise. The class of drift this ADR closes is precisely the class where a project shipped for months on a warning nobody read. Refusing at the gate keeps the invariant load-bearing."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-001",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "The repo-root wrangler manifest is the single declaration of the Worker's deploy shape",
|
|
5
|
+
"description": "A `wrangler.toml` (or the equivalent `wrangler.jsonc`) at the repo root is the sole declaration of the Worker's deploy shape. It carries the Worker `name`, the entrypoint `main`, a pinned `compatibility_date`, any `compatibility_flags`, and every non-secret binding the runtime needs: KV namespaces, D1 databases, R2 buckets, Durable Object namespaces, static-assets binding, and non-secret environment variables. Secret bindings are NOT declared in the manifest (wrangler 4.x has no `[secrets]` block, no `secrets.required[]` list, and no empty-value binding entry for secrets); the vendor treats every env-accessor reference from Worker code as an implicit secret binding declaration and enforces its presence at deploy time by refusing `wrangler deploy` when a referenced secret has not been set on the target. Nothing outside the manifest may configure a non-secret binding at deploy time; a non-secret binding referenced from Worker code but absent from the manifest is a build refusal (an implicitly-referenced secret is caught by the vendor's own pre-deploy refusal instead). No secret VALUE ever appears in the manifest.",
|
|
6
|
+
"category": "technical",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A scattered deploy configuration is the failure mode this blueprint exists to end. If bindings are declared in ad-hoc scripts, CI environment blocks, or hand-edited before deploy, no one knows what the deployed Worker actually looks like. A single manifest at a known path makes the deploy shape legible to humans, to CI gates, to the vendor's deploy step, and to review of every change that touches a binding.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:01-manifest"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-002",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "One deploy adapter module is the sole caller of the deploy CLI",
|
|
5
|
+
"description": "The project exposes a single Deploy Adapter module that wraps the deploy CLI (the vendor's `wrangler` binary when the default vendor is in play). Every path that uploads a version, promotes a version, lists versions, or reads deploy state routes through this module. Nothing else in the project source tree spawns the CLI, imports the vendor SDK, or issues an HTTP call to the vendor's deploy API. The module exposes a fixed named-verb surface (`uploadVersion`, `promoteVersion`, `listVersions`, `resolveNewestOfMain`, `describeVersion`) that is stable across the blueprint's major version.",
|
|
6
|
+
"category": "technical",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A vendor-neutral adapter port keeps the project free to change deploy vendors under the same interface. It also removes the class of bugs where two paths call the CLI with different flags and drift silently. One module, one boundary, one behaviour. The blueprint mandates the CONTRACT and defaults the VENDOR; a project that supersedes the default vendor swaps only the adapter's implementation.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:02-adapter-boundary"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-003",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Every merge to the main branch uploads a Worker version addressable at a stable preview alias URL",
|
|
5
|
+
"description": "The CI pipeline runs a build+upload step on every merge to the main branch. The step produces an uploaded Worker version (the vendor's version primitive) with two addressable URLs recorded on the CI run: a permanent per-version-id URL, and a stable ALIAS URL fixed to the string `main` (or an equivalent operator-chosen alias) that always resolves to the newest-of-main upload. The alias URL never changes across re-uploads; the version-id URL is unique per upload and durable. The uploaded version does NOT serve production traffic; it exists only at the preview URLs until an explicit promote step runs. The version id and both URLs are surfaced in the CI run output.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Uploading a version on merge without promoting it separates two concerns most teams tangle at their cost: 'is the artefact built and cleanly uploaded' from 'is production serving it now'. The stable preview alias URL is the shape a stakeholder can bookmark and share; the version-id URL is the shape a change-review workflow references verbatim. Both matter and both come from the same upload step.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:03-preview-upload"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-004",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Production only changes via an explicit promote step; no upload path auto-promotes",
|
|
5
|
+
"description": "Production traffic serving is a distinct action from uploading a version. No CI path may take an uploaded version and route production traffic to it as a side effect of the upload. Production only changes when a Promote step runs and names the version id to serve. The promote step is authored as a separate CI workflow triggered by explicit operator action (`workflow_dispatch` on GitHub Actions or the equivalent manual-trigger primitive on other CI platforms). The promote workflow accepts one input: `versionId` (empty defaults to the newest-of-main resolved from the preview alias); every promote emits a structured record naming the version id promoted, the operator principal that triggered the workflow, the previously-serving version id, and the timestamp.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "The failure mode this ends: a merge lands, the CI pipeline deploys straight to production, and nobody notices the bad release until the phone rings. Decoupling upload from promote makes the ship-to-production act a first-class human decision. The default of newest-of-main keeps the promote fast for the common case; the explicit versionId keeps rollback and hotfix promotes on the same code path.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:04-explicit-promote"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-005",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Preview and production surfaces are addressable at distinct URLs both discoverable from the manifest",
|
|
5
|
+
"description": "The deployed application is reachable at two distinct kinds of URL: a PREVIEW surface (per-version alias URLs and per-version-id URLs, both provided by the vendor at upload time on the workers.dev subdomain) and a PRODUCTION surface (a route or custom domain declared in `wrangler.toml` under a `route`/`routes`/`workers_dev` block, or a mapped custom hostname). A `deploy status` verb on the Deploy Adapter surfaces both URL kinds for the current state without requiring an operator to consult the vendor dashboard. The preview alias URL and the production URL are never the same string; a project that would collapse them into one URL is a misconfiguration the adapter refuses.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Two URLs, two purposes. The preview URL is where a change lives before promote, where stakeholder review happens, where end-to-end probes hit the newest-of-main. The production URL is where users hit the promoted version. Collapsing them is the failure mode where reviewing a change means reviewing production; keeping them distinct is what makes the promote step meaningful.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:05-url-model"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-006",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Secret bindings resolve through the project's secrets contract, never plaintext in the wrangler manifest",
|
|
5
|
+
"description": "Every secret the Worker reads at runtime is referenced implicitly through the runtime's env accessor (in the default JS/TS Worker, `env.<NAME>`); wrangler 4.x has no `[secrets]` block, no `secrets.required[]` list, and no empty-value binding entry for secrets, and the vendor treats every such env-accessor reference from Worker code as an implicit secret binding declaration, refusing `wrangler deploy` when a referenced secret has not been set on the target. Each such name is populated on the deploy target through the vendor's own secret-set flow (first-deploy via `wrangler deploy --secrets-file <tmp>`, steady-state via `wrangler secret put <NAME>`; see `assets/wrangler-samples/bootstrap-vs-steady-state.md`). The value is sourced from the project's secrets contract (as fixed by the `security-secrets-management` blueprint at slug `security-secrets-management` when applied, or by the equivalent project-authored contract). No secret VALUE ever lives in `wrangler.toml`, in a committed environment file, in a CI variable readable outside the promote job, or in the CI run's captured logs. A CI-side redactor scrubs any log line that would emit a resolved secret value.",
|
|
6
|
+
"category": "security",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Secrets in deploy config is one of the two shapes of leak this blueprint refuses (the other is production auto-promote). Declaring bindings by name only forces the value to arrive through a controlled channel and keeps the manifest safe to review in a PR. The blueprint mandates the CONTRACT (values arrive through the secrets pipeline); the vendor default binds through `wrangler secret put`.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:06-secrets-boundary"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-007",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "A build-and-upload CI workflow runs on every merge to the main branch and records the uploaded version id",
|
|
5
|
+
"description": "A CI workflow named `build-and-upload` (or the project's chosen equivalent) triggers on `push` to the main branch (and on any linear-history proxy the project uses). It checks the tree out, installs dependencies at the pinned versions, runs the project's build step, then invokes the Deploy Adapter's `uploadVersion` verb naming the operator-chosen preview alias string. On success it writes the uploaded version id, the version-id URL, and the preview alias URL to the CI run's job summary and to a structured output the promote workflow reads. The workflow authenticates to the vendor through named CI secrets (a vendor API token and a vendor account id); the token is scoped to the Worker's account and never appears in any log line.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "The build-and-upload workflow is the mechanism half of REQ-003: every merge produces an uploaded, addressable version, without touching production. Making the version id and URLs discoverable in the CI run output is what makes the promote step's `newest-of-main` default computable and what makes the change reviewable at the preview URL by anyone with the CI run link.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:07-ci-build-upload"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-008",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "A promote CI workflow runs on explicit manual trigger and accepts an optional versionId input",
|
|
5
|
+
"description": "A CI workflow named `promote` (or the project's chosen equivalent) triggers only on manual operator action (`workflow_dispatch` on GitHub Actions or the equivalent explicit-trigger primitive on other CI platforms). It accepts one input field `versionId`: when supplied, the workflow promotes that exact version; when blank, the workflow calls the Deploy Adapter's `resolveNewestOfMain` verb to look up the current version id behind the preview alias and promotes THAT. It then invokes `promoteVersion` on the Deploy Adapter and, on success, invokes the served-surface verifier (REQ-010) before declaring the run successful. The workflow authenticates through the same named vendor CI secrets as `build-and-upload` and emits a structured record of the promote for the deploy log.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "One workflow for both cases keeps the promote path narrow and reviewable. The empty-input default answers the common case (ship what merged); the explicit-id input answers hotfix promotes and rollbacks without a second code path. Every promote runs through the same served-surface verifier gate so no promote can quietly ship a broken version.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:08-ci-promote"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-009",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Rollback is a promote of a prior version id; the promote workflow is the sole ship-to-production path",
|
|
5
|
+
"description": "Rolling production back to a previous version is not a distinct code path in the project's deploy tooling. It is the same `promote` workflow (REQ-008) triggered with the prior version id supplied as the `versionId` input. The prior version id is discoverable by calling the Deploy Adapter's `listVersions` verb, which returns the recent history with the currently-serving id marked. A project may surface a `wrangler rollback` shortcut in operator documentation for convenience, but at the contract level the shortcut is a promote of the second-most-recent version id and the audit trail records it the same way. No project-authored `rollback` verb bypasses the promote workflow's structured record or the post-promote verifier.",
|
|
6
|
+
"category": "functional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Two ship paths is one too many. If rollback has its own bespoke script, the script drifts from the promote path in exactly the moments an incident is the wrong time to discover drift. Framing rollback as a promote of a known-good version id keeps the ship path narrow, the audit shape uniform, and the post-promote verifier applied unconditionally.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:09-rollback"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-010",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Every promote runs bounded served-surface probes against the production URL and fails the release on breach",
|
|
5
|
+
"description": "Immediately after a successful `promoteVersion` call, the promote workflow (REQ-008) invokes the Served-surface Verifier (TAC-1305). The verifier hits a fixed set of probe paths on the PRODUCTION URL (not the preview URL) with bounded retry semantics: at least three probe paths chosen by the project, each requested at most six times over at most sixty seconds, with a per-request timeout at most five seconds. A probe passes when the response status is in the project-declared success set and the response body carries the expected shape (for a health probe, a body containing the version-id string that was just promoted; for a smoke path, a project-declared invariant string). If any probe path fails every retry the workflow exits non-zero with a stable code `PROMOTE_VERIFY_FAILED`, records the failed probe path, the response status seen, the elapsed time, and refuses to mark the release successful.",
|
|
6
|
+
"category": "nonFunctional",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "A promote that does not verify the served surface is a promote taken on trust of the vendor's own success signal. The vendor's success signal covers 'the version is now the serving version', which is not the same as 'the served surface answers correctly'. Bounded retries are the discipline that catches propagation-lag class failures without turning transient blips into a stuck workflow.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:10-verify-served"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-011",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Local dev-mode is an emulator; the ship gate never treats a dev-mode signal as authoritative",
|
|
5
|
+
"description": "The vendor's local development mode (`wrangler dev` on the default vendor) is an emulator, not the deployed runtime. It approximates the runtime shape but carries known behavioural differences (differing regular-expression engines, differing static-assets ordering, differing binding-emulation surface, differing timeout behaviour). The project may use dev-mode for developer-loop iteration. The ship gate does not: no test authored against `wrangler dev` counts as passing coverage for a deployed AC; the coverage tag `deployed` on any AC requires the served-surface probe hit an actual uploaded Worker (preview URL is fine; production URL is fine; dev-mode local URL is not). A project-side lint or CI check catches an AC-to-TC binding that attempts to substitute a dev-mode observation for a deployed one.",
|
|
6
|
+
"category": "technical",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "The reason a runtime-verify layer exists in RCF is that codebase-level tests cannot cover deployed behaviour. Letting an emulator stand in for the deployed runtime re-opens exactly the class of drift the deployed-scope tag exists to close. Naming the class of dev-mode-only tests inadmissible-as-deployed-coverage is the discipline.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:11-dev-mode-drift"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"reqId": "deploy-cloudflare-workers-REQ-012",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"title": "Every uploaded version carries build-provenance attributes readable at runtime",
|
|
5
|
+
"description": "Every version uploaded by the `build-and-upload` workflow carries three provenance attributes accessible from within the Worker at runtime: the commit sha of the source tree the version was built from, the ISO 8601 timestamp of the build, and the URL of the CI run that produced the upload. The three values are injected into the Worker's build (as build-time constants baked into the bundle, as `vars` populated by the CI step, or as a runtime-readable metadata surface the Deploy Adapter's `describeVersion` verb returns; the project picks the mechanism). A health probe exposes them on a fixed path; the response body carries a stable JSON shape whose `versionSha`, `builtAt`, and `ciRunUrl` fields are the served-surface verifier's evidence that the promoted version is the version it thinks it promoted.",
|
|
6
|
+
"category": "technical",
|
|
7
|
+
"domain": "deploy",
|
|
8
|
+
"priority": "must",
|
|
9
|
+
"rationale": "Without provenance the served-surface verifier cannot tell a successful promote from a stale response served by a routing layer that has not converged. Baking provenance into the version and surfacing it on a health probe is what makes the verifier's success signal load-bearing; it is also what makes incident triage answerable in one request.",
|
|
10
|
+
"tags": [
|
|
11
|
+
"blueprint:deploy-cloudflare-workers",
|
|
12
|
+
"category:12-provenance"
|
|
13
|
+
],
|
|
14
|
+
"version": "1.0.0",
|
|
15
|
+
"status": "approved",
|
|
16
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
17
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
18
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-1301-deploy-cloudflare-workers-deploy-adapter",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Deploy Adapter",
|
|
8
|
+
"purpose": "The one project module that talks to the deploy vendor. Wraps the vendor's CLI (or SDK) behind a fixed named-verb surface every other module imports. Uploads versions, promotes versions, lists version history, resolves the newest-of-main from the preview alias, and describes any single version's provenance and URLs. Nothing else in the project spawns the vendor CLI or issues a vendor deploy call.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Expose `uploadVersion({ previewAlias })` that uploads the current build to the vendor and returns `{ versionId, versionIdUrl, previewAliasUrl }`; refuse an empty `previewAlias` with `DEPLOY_PREVIEW_ALIAS_REQUIRED` (AC-12102-2, AC-12103-1).",
|
|
11
|
+
"Expose `promoteVersion({ versionId })` that routes production traffic to the named version and returns `{ promotedVersionId, versionSha, previousVersionId }`; the returned `promotedVersionId` is the vendor-assigned version UUID (the string `wrangler versions deploy` took) and the returned `versionSha` is the git commit sha of the source tree the promoted version was built from (read from the version's provenance surface via `describeVersion`); refuse when `versionId` is absent from `listVersions()` with `DEPLOY_VERSION_NOT_FOUND` (AC-12102-3, AC-12108-3).",
|
|
12
|
+
"Expose `listVersions()` returning the recent version history with the currently-serving id marked (AC-12109-1).",
|
|
13
|
+
"Expose `resolveNewestOfMain()` that returns the version id currently behind the operator-chosen preview alias by reading `wrangler versions list --json` and picking the item with the greatest `metadata.created_on` whose `annotations['workers/alias']` matches the alias; there is no vendor CLI verb that maps an alias to a version id directly (AC-12108-2).",
|
|
14
|
+
"Expose `describeVersion({ versionId })` returning provenance (`versionSha`, `builtAt`, `ciRunUrl`) and URLs (`versionIdUrl`) for the named version; `versionSha` is the git commit sha baked into the version's bundle by `build-and-upload`, distinct from the version UUID `versionId` names (AC-12112-1, AC-12112-2).",
|
|
15
|
+
"Expose `resolveSubdomain()` that returns the account's workers.dev subdomain string every URL-assembly path needs; reads the `WORKERS_DEV_SUBDOMAIN` env var when set (project pin) and otherwise queries the vendor's `GET /accounts/<accountId>/workers/subdomain` REST endpoint; caches the value for the process's lifetime (AC-12105-1).",
|
|
16
|
+
"Refuse a manifest whose production route resolves to the same host as the preview alias URL with `DEPLOY_URL_COLLAPSED` (AC-12105-2).",
|
|
17
|
+
"Route every CLI invocation through a redactor that scrubs the vendor API token and account id from every emitted log line (AC-12107-3, AC-12106-2)."
|
|
18
|
+
],
|
|
19
|
+
"internalStructure": "One stateless class per process with an injected vendor binding and an injected redactor. The vendor binding is a project-authored module implementing the port in the interfaces block; the default vendor binding shells to the `wrangler` CLI and lives under the same package as the adapter. Every verb is a thin translation from the named surface to a vendor CLI invocation (or SDK call) plus response parsing plus provenance-URL assembly.",
|
|
20
|
+
"interfaces": [
|
|
21
|
+
{
|
|
22
|
+
"name": "vendorBinding",
|
|
23
|
+
"kind": "read-write-api",
|
|
24
|
+
"description": "Project-supplied vendor binding implementing `uploadArtefact({ configPath, previewAlias })`, `deployVersion({ versionId })`, `listVersions()`, `resolveAlias({ alias })`, `getSubdomain({ accountId })`. The default binding shells to `wrangler versions upload --preview-alias <alias>`, `wrangler versions deploy <versionId>`, and `wrangler versions list --json` respectively; `resolveAlias` filters the `versions list --json` output on `annotations['workers/alias']` and picks the newest by `metadata.created_on` because wrangler 4.x has no CLI verb that resolves an alias to a version id (`wrangler versions view` accepts a version UUID only); `getSubdomain` calls the vendor's `GET /accounts/<accountId>/workers/subdomain` REST endpoint because `wrangler whoami` does not return the subdomain."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "redactor",
|
|
28
|
+
"kind": "callback",
|
|
29
|
+
"description": "Log-line filter that replaces any bytes matching the vendor API token or account id with a fixed placeholder before emitting; runs on every stdout and stderr line the vendor CLI produces."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"name": "manifest",
|
|
33
|
+
"kind": "read-api",
|
|
34
|
+
"description": "The wrangler-manifest loader (TAC-1302) resolving the current Worker's config, the production route or custom-domain declaration, and the declared binding names."
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"dependencies": [
|
|
38
|
+
{
|
|
39
|
+
"name": "Wrangler Manifest",
|
|
40
|
+
"kind": "tac",
|
|
41
|
+
"tacId": "TAC-1302-deploy-cloudflare-workers-wrangler-manifest",
|
|
42
|
+
"description": "Upstream source of the config the adapter passes to the vendor CLI, and the manifest the collapsed-URL guard reads."
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "Preview URL Resolver",
|
|
46
|
+
"kind": "tac",
|
|
47
|
+
"tacId": "TAC-1303-deploy-cloudflare-workers-preview-url-resolver",
|
|
48
|
+
"description": "Assembles the preview alias URL and version-id URL strings the adapter returns; consulted from `uploadVersion` and `describeVersion`."
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"tradeoffs": "The adapter is process-local and stateless; every call reaches the vendor. That means a chain of adapter calls in one CI step costs one vendor round-trip per call rather than a shared session. The trade keeps the adapter easy to reason about and easy to reimplement against a different vendor. A project that wants a session-shared invocation supplies a vendor binding whose backing is a long-lived process rather than a CLI spawn per call; the port shape does not change.",
|
|
52
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
53
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
54
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-1302-deploy-cloudflare-workers-wrangler-manifest",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Wrangler Manifest",
|
|
8
|
+
"purpose": "The repo-root deploy-configuration file (`wrangler.toml` or `wrangler.jsonc`) as loaded, validated, and exposed to the Deploy Adapter. Parses the manifest into an object the adapter and the CI gates consult, enforces the shape rules (required top-level keys, declared bindings, no inline secrets, no collapsed URLs), and refuses malformed or leaky manifests loudly.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Parse `wrangler.toml` (or `wrangler.jsonc`) at the repo root; refuse absence with `WRANGLER_MANIFEST_MISSING` (AC-12101-1).",
|
|
11
|
+
"Validate the top-level keys `name`, `main`, `compatibility_date` are present and correctly typed; validate `main` resolves to an existing entry file; validate `compatibility_date` matches `\\d{4}-\\d{2}-\\d{2}` (AC-12101-1).",
|
|
12
|
+
"Cross-check every binding name referenced from the Worker source (via env-accessor scans keyed by binding name) against the manifest declarations; refuse a missing declaration with `WRANGLER_BINDING_UNDECLARED` naming the offending source path and the missing binding (AC-12101-2).",
|
|
13
|
+
"Refuse a manifest that carries any inline secret value; scan the parsed object for keys under the vendor's secret-declaration primitive whose value is not an empty declaration (AC-12101-3, AC-12106-1).",
|
|
14
|
+
"Refuse a manifest whose production route stanza resolves to the same host as the preview alias URL with `DEPLOY_URL_COLLAPSED` (AC-12105-2).",
|
|
15
|
+
"Expose a `bindings()` accessor listing every declared binding (kind, name) for downstream consumers.",
|
|
16
|
+
"Expose a `productionUrl()` accessor deriving the production URL from the `routes`/`route`/`workers_dev`/custom-domain declaration."
|
|
17
|
+
],
|
|
18
|
+
"internalStructure": "One parser module per format (TOML and JSONC), one validator that walks the parsed object against the shape rules, one binding-usage scanner that walks the Worker source AST for env-accessor patterns, and one URL-derivation module that inspects the routes stanza. All pure functions; no I/O outside the initial file read.",
|
|
19
|
+
"interfaces": [
|
|
20
|
+
{
|
|
21
|
+
"name": "manifestFile",
|
|
22
|
+
"kind": "read-api",
|
|
23
|
+
"description": "Reads `wrangler.toml` or `wrangler.jsonc` at the repo root. The file's presence is required; the file's format is autodetected from the extension."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"name": "workerSourceScanner",
|
|
27
|
+
"kind": "read-api",
|
|
28
|
+
"description": "AST or regex scanner over the Worker source tree that emits every binding name referenced through env-accessor patterns (for the default JS/TS Worker, `env.<NAME>.<method>` and `process.env.<NAME>` are both matched)."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"name": "bindings",
|
|
32
|
+
"kind": "read-api",
|
|
33
|
+
"description": "Structured list of declared bindings emitted for downstream consumers. Each entry names the binding kind (KV, D1, R2, Durable Object, static assets, var, secret, service, queue) and the binding name."
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
"name": "productionUrl",
|
|
37
|
+
"kind": "read-api",
|
|
38
|
+
"description": "Returns the production URL derived from the manifest. When multiple routes are declared, returns the ordered list; when `workers_dev = true`, returns the workers.dev host."
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"dependencies": [],
|
|
42
|
+
"tradeoffs": "The loader owns validation but does not own the vendor's own manifest-level validation (which happens later at the vendor CLI). Two-stage validation means a manifest that passes this loader can still fail the vendor's own load; the trade keeps the loader project-local and fast (no vendor round-trip on every CI step) while catching the classes this blueprint cares about (undeclared bindings, inline secrets, collapsed URLs) before the vendor call. A project can point the loader at a project-authored TOML dialect (a preprocessor step) by wrapping the manifestFile interface.",
|
|
43
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
44
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
45
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-1303-deploy-cloudflare-workers-preview-url-resolver",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Preview URL Resolver",
|
|
8
|
+
"purpose": "The single project source of the string patterns for the two preview URL kinds (per-version-id URL, stable alias URL) and the mapping between an alias string and the version id it currently resolves to. Consulted by the Deploy Adapter's `uploadVersion` and `describeVersion` verbs and by every path that needs to reach the preview surface for review or verification.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Assemble the per-version-id URL for a given version id and the currently-configured Worker name and vendor subdomain (AC-12103-1, AC-12103-2).",
|
|
11
|
+
"Assemble the stable preview alias URL for a given alias string and the currently-configured Worker name and vendor subdomain; ensure the alias is quoted verbatim in the host segment (AC-12102-2, AC-12103-1).",
|
|
12
|
+
"Given an alias string, query the vendor for the version id currently behind the alias and return it (`resolveNewestOfMain` on the Deploy Adapter delegates here) (AC-12108-2).",
|
|
13
|
+
"Refuse an alias string that would collide with the production route's host segment; return `DEPLOY_URL_COLLAPSED` (AC-12105-2).",
|
|
14
|
+
"Guarantee the preview URL host segment can never equal the production URL host segment; the invariant is a property test at build time (AC-12105-3).",
|
|
15
|
+
"Expose a `probeUrl(kind, id-or-alias)` verb that returns the URL to hit for a given probe target (`versionId`, `alias`, or `production`), so the Served-surface Verifier need not know URL assembly."
|
|
16
|
+
],
|
|
17
|
+
"internalStructure": "Pure string-assembly module plus a thin query wrapper over the vendor's alias-lookup call. No cache: every alias query goes to the vendor because the alias is expected to change on every upload and the freshness cost of caching is not worth the complexity.",
|
|
18
|
+
"interfaces": [
|
|
19
|
+
{
|
|
20
|
+
"name": "workerIdentity",
|
|
21
|
+
"kind": "read-api",
|
|
22
|
+
"description": "Reads the Worker name from the wrangler manifest. Reads the vendor account's workers.dev subdomain from the Deploy Adapter's `resolveSubdomain()` verb (which honours a `WORKERS_DEV_SUBDOMAIN` env-var pin ahead of calling the vendor's `GET /accounts/<accountId>/workers/subdomain` REST endpoint, because no wrangler CLI verb returns the subdomain). Returns both as strings the URL-assembly functions consume."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "aliasQuery",
|
|
26
|
+
"kind": "read-api",
|
|
27
|
+
"description": "Queries the vendor for the version id currently behind an alias by reading `wrangler versions list --json` and filtering on `annotations['workers/alias']`, returning the item with the greatest `metadata.created_on`; there is no direct CLI verb (`wrangler versions view` accepts a version UUID only). Returns the id or a stable `DEPLOY_ALIAS_UNKNOWN` error when no version carries the alias annotation."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "probeUrl",
|
|
31
|
+
"kind": "read-api",
|
|
32
|
+
"description": "Named-verb URL accessor for downstream consumers. `probeUrl('versionId', 'v-123')` returns the per-version URL; `probeUrl('alias', 'main')` returns the alias URL; `probeUrl('production', null)` returns the production URL from the manifest."
|
|
33
|
+
}
|
|
34
|
+
],
|
|
35
|
+
"dependencies": [
|
|
36
|
+
{
|
|
37
|
+
"name": "Wrangler Manifest",
|
|
38
|
+
"kind": "tac",
|
|
39
|
+
"tacId": "TAC-1302-deploy-cloudflare-workers-wrangler-manifest",
|
|
40
|
+
"description": "Reads the Worker name and the production route stanza; the collapsed-URL invariant is checked against `productionUrl()`."
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
"tradeoffs": "The resolver treats the vendor's URL-string patterns as stable within the blueprint's major version. When the vendor changes the pattern (a new subdomain scheme, a new alias-in-host format), a blueprint major bump is what tracks the change; a project that pinned an older pattern by hand-editing the resolver loses the invariant guard. The trade is a small coupling to the vendor's public URL contract in exchange for one place to change when it moves.",
|
|
44
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
45
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
46
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"tacId": "TAC-1304-deploy-cloudflare-workers-promote-gate",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "approved",
|
|
7
|
+
"name": "Promote Gate",
|
|
8
|
+
"purpose": "The project-side guard that enforces production only changes on an explicit operator promote. Wraps the `promote` workflow's input handling, its version-id resolution, its call into the Deploy Adapter, and its post-promote invocation of the Served-surface Verifier. Emits the structured deploy-log record every promote leaves behind.",
|
|
9
|
+
"responsibilities": [
|
|
10
|
+
"Accept the `versionId` input from the promote workflow trigger; when empty, invoke `deployAdapter.resolveNewestOfMain()` to fill it (AC-12108-1, AC-12108-2).",
|
|
11
|
+
"Refuse a `versionId` absent from `deployAdapter.listVersions()` before any vendor call is issued; return `DEPLOY_VERSION_NOT_FOUND` (AC-12108-3).",
|
|
12
|
+
"Invoke `deployAdapter.promoteVersion({ versionId })`; capture the returned `{ promotedVersionId, versionSha, previousVersionId }` for the deploy-log record. `promotedVersionId` is the vendor-assigned version UUID; `versionSha` is the git commit sha of the source tree the promoted version was built from, read from the version's provenance surface; both are required on the record and both feed the Served-surface Verifier (the verifier reconciles the served health-probe body's `versionSha` against the record's `versionSha`) (AC-12104-3, AC-12109-1).",
|
|
13
|
+
"Immediately invoke the Served-surface Verifier against the production URL, passing the promote record's `versionSha` as the substitution value for `expectShape.versionSha` in the health-probe declaration; on any verifier failure exit non-zero with `PROMOTE_VERIFY_FAILED` and refuse to mark the release successful (AC-12109-3, AC-12110-1, AC-12110-3).",
|
|
14
|
+
"Emit the deploy-log record with fields `promotedVersionId`, `versionSha`, `promotedBy`, `previousVersionId`, `promotedAt`; every field is populated; no field carries a secret value (AC-12104-3).",
|
|
15
|
+
"Refuse to run when the invocation context is not the platform's explicit-manual-trigger primitive (a `workflow_dispatch` guard as the first step of the workflow) (AC-12104-1, AC-12104-2)."
|
|
16
|
+
],
|
|
17
|
+
"internalStructure": "One workflow-orchestration function per CI platform (the default GitHub Actions form is shipped as an asset; other platforms adapt the same shape). The function is stateless; the workflow's own outputs are the durable state. The deploy-log record is written to a project-chosen sink (a JSONL file in a durable location, an audit event bus, a database table) through an injected `deployLog.append` callback.",
|
|
18
|
+
"interfaces": [
|
|
19
|
+
{
|
|
20
|
+
"name": "deployAdapter",
|
|
21
|
+
"kind": "read-write-api",
|
|
22
|
+
"description": "The Deploy Adapter port (TAC-1301). The promote gate calls `listVersions`, `resolveNewestOfMain`, and `promoteVersion` through this interface."
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "verifier",
|
|
26
|
+
"kind": "read-api",
|
|
27
|
+
"description": "The Served-surface Verifier callable that runs the post-promote probes and returns pass or a `PROMOTE_VERIFY_FAILED` failure description."
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
"name": "deployLog",
|
|
31
|
+
"kind": "callback",
|
|
32
|
+
"description": "Append callback invoked with the promote record `{ promotedVersionId, versionSha, promotedBy, previousVersionId, promotedAt }` on every successful promote and on every verifier-failed promote."
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"name": "triggerContext",
|
|
36
|
+
"kind": "read-api",
|
|
37
|
+
"description": "Returns the platform's trigger information (event name, actor login). The gate refuses to proceed when the event name is not the platform's explicit-manual-trigger name (`workflow_dispatch` on GitHub Actions)."
|
|
38
|
+
}
|
|
39
|
+
],
|
|
40
|
+
"dependencies": [
|
|
41
|
+
{
|
|
42
|
+
"name": "Deploy Adapter",
|
|
43
|
+
"kind": "tac",
|
|
44
|
+
"tacId": "TAC-1301-deploy-cloudflare-workers-deploy-adapter",
|
|
45
|
+
"description": "Every version operation routes through the adapter; no direct vendor CLI call from the gate."
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"name": "Served-surface Verifier",
|
|
49
|
+
"kind": "tac",
|
|
50
|
+
"tacId": "TAC-1305-deploy-cloudflare-workers-served-surface-verifier",
|
|
51
|
+
"description": "The post-promote probe layer; the gate invokes the verifier and honours its failure signal."
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
"tradeoffs": "The gate is coupled to the workflow platform's explicit-trigger primitive. A project that runs on a CI platform without a distinct manual-trigger event needs a project-authored wrapper that supplies the equivalent (a manual-approval step; a webhook with an operator token check). The trade is the workflow platforms that ship this primitive natively (GitHub Actions, GitLab CI's manual jobs, Buildkite's block steps) all get the invariant enforced cheaply; the rest layer their own equivalent above.",
|
|
55
|
+
"createdAt": "2026-08-30T00:00:00Z",
|
|
56
|
+
"updatedAt": "2026-08-30T00:00:00Z"
|
|
57
|
+
}
|