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,77 @@
|
|
|
1
|
+
# Persistence data D1 blueprint guide
|
|
2
|
+
|
|
3
|
+
## What it is
|
|
4
|
+
|
|
5
|
+
A default durable-store floor for small greenfield rcf-lite projects deployed on Cloudflare Workers. The blueprint contributes the WHAT of a Workers-tier persistence pattern: how the D1 binding is read, how the store facade wraps it, how schema evolves through wrangler-owned numbered migrations, how the deploy pipeline gates the Worker on the apply succeeding first, how the prepared-statement discipline closes the SQL-injection surface by construction, how multi-statement atomicity is expressed through batch, how the store event log looks, and how recovery is available on two paths (Time Travel in the vendor and portable export off the vendor). The default engine is one Cloudflare D1 database; other engines behind the same facade contract on supersede.
|
|
6
|
+
|
|
7
|
+
Concretely, the blueprint ships seven requirements, seven user stories (twenty acceptance criteria), four architecture components, and five architecture decision records. Two ADRs are `scope: global` on the topics `persistenceStore` (the engine choice) and `migrationDiscipline` (the wrangler-owned deploy-gated posture); the other three are scope-local operational ADRs (event secrecy, module boundary, recovery model) that a composing blueprint does not conflict with by default.
|
|
8
|
+
|
|
9
|
+
## What it is not
|
|
10
|
+
|
|
11
|
+
Not a domain schema. The tables the project's own entities live in are project-authored, on top of the migration directory the project maintains. The blueprint governs the store facade contract and the migration discipline; the domain shape is the project's own responsibility.
|
|
12
|
+
|
|
13
|
+
Not an ORM. There is no query builder, no active-record layer, no framework-shaped abstraction between the facade's named verbs and the D1 prepared-statement surface. Projects that want an ORM (Drizzle, Kysely) wire it inside the facade's implementation and preserve the outward verb surface; the prepared-statement discipline (static SQL literals only) survives the ORM choice because most ORMs emit static SQL from typed queries at build time.
|
|
14
|
+
|
|
15
|
+
Not a Worker deploy blueprint. The deploy-gate TAC assumes a `wrangler deploy` step exists on the CI surface; a companion `deploy-cloudflare-workers` blueprint (round-2 sibling, unshipped at v1.0.0) is the natural owner of that surface. Until it ships, projects wire their own `wrangler deploy` step and the deploy-gate contract binds against it.
|
|
16
|
+
|
|
17
|
+
Not a secrets-management blueprint. The CI credential that runs `wrangler d1 migrations apply` and `wrangler deploy` (the `CLOUDFLARE_API_TOKEN`, or the OAuth-scoped credential the vendor issues) is a secret whose storage and rotation posture the `security-secrets-management` blueprint governs. This blueprint references the credential by role, not by name or storage path.
|
|
18
|
+
|
|
19
|
+
Not a CI-pipeline blueprint. The deploy-gate TAC contributes the requirement that `wrangler d1 migrations apply` orders strictly before `wrangler deploy` and the deploy job refuses on apply failure; the CI file that implements that ordering is the concern of the `ci-pipeline` blueprint or the project's own CI-authoring practice.
|
|
20
|
+
|
|
21
|
+
Not a logical-dump story beyond the vendor's export. Backups are `wrangler d1 export` artifacts; cross-engine migration and portable dumps beyond D1's own `.sql` export are out of scope. Projects that need a schema-agnostic dump layer a project-authored dump runner beside the file-level runner.
|
|
22
|
+
|
|
23
|
+
Not a connection pool. The D1 binding is request-scoped; the facade holds no long-lived engine handle. Projects that need connection pooling have picked the wrong engine tier; supersede ADR-1401.
|
|
24
|
+
|
|
25
|
+
Not a replication or failover story. D1's read-replica surface (accessed via `withSession`) targets read scaling, not failover. Projects that need failover semantics supersede ADR-1401 with an alternate engine that provides them.
|
|
26
|
+
|
|
27
|
+
## When to reach for it
|
|
28
|
+
|
|
29
|
+
Reach for the persistence-data-d1 blueprint when:
|
|
30
|
+
|
|
31
|
+
- The project is a small greenfield rcf-lite deployment on Cloudflare Workers (one deployable, one small team, no ops team standing by, the project's deploy target IS the Workers edge substrate).
|
|
32
|
+
- The domain has a natural relational shape (bounded set of entities with well-defined relationships) that SQL expresses cleanly.
|
|
33
|
+
- Zero-infrastructure persistence at the vendor tier is a feature (no database server to run, no connection pool to size, no network hop outside the vendor's edge substrate on the request path).
|
|
34
|
+
- The steady-state working set fits inside D1's currently published per-database ceiling on the project's plan tier (a currently-published upper bound of 10 GB per D1 database on the Paid plan; 500 MB on the Free plan) and the per-Worker-invocation query count fits inside the plan's limit (currently 1000 on Paid, 50 on Free).
|
|
35
|
+
- The recovery model that fits is 'rewind in place within the vendor recovery window, or reload from a portable off-vendor export artifact for anything longer'; Time Travel is the primary fast path.
|
|
36
|
+
- The migration story that fits is 'wrangler CLI applies numbered `.sql` files, gated by the deploy pipeline, no boot-time runner'; the project accepts that a schema-behind-the-code state is closed at CI time, not at request time.
|
|
37
|
+
|
|
38
|
+
## When it does not fit
|
|
39
|
+
|
|
40
|
+
Do not reach for the persistence-data-d1 blueprint when:
|
|
41
|
+
|
|
42
|
+
- The deploy target is not Cloudflare Workers. D1 is only accessible through the Workers runtime; a project deployed on a Node server, a container platform, or a non-Workers serverless surface picks a different engine. The sibling persistence-data-sqlite blueprint (single-file SQLite for a Node-tier deployment) is the natural pair; a project that needs Postgres supersedes ADR-1401 with a project-level ADR.
|
|
43
|
+
- Multi-writer scale across regions, hot standby replication, or true failover are project requirements. D1's read-replica surface is a read-scaling primitive, not a failover primitive; a project that needs failover supersedes ADR-1401 with an alternate engine that provides them.
|
|
44
|
+
- The working set is genuinely too large for the currently published per-database D1 ceiling on the project's plan tier. At that scale a project's options are to shard across multiple D1 databases (a shape the blueprint does not prescribe), or to supersede ADR-1401 with a Postgres or equivalent engine that lifts the ceiling.
|
|
45
|
+
- The domain shape is genuinely non-relational (opaque blob storage, event streams, time-series with a fixed retention model). A different blueprint (a KV-store blueprint, an event-sourced blueprint, a time-series blueprint) owns those shapes; supersede with a project-level ADR and skip this blueprint.
|
|
46
|
+
- The project has a hard requirement for a boot-time migration runner discipline (a service that reads the schema version at start and applies pending migrations before serving). Reach for the persistence-data-sqlite blueprint instead; its `migrationDiscipline` topic is exactly that shape. The two blueprints deliberately conflict on `migrationDiscipline` on this exact difference.
|
|
47
|
+
- The project has a hard requirement to run the same store engine locally in the developer's process (a small tool that ships with an embedded store, a CLI that reads from the store without a Workers runtime). D1 is only fully realised inside a Workers runtime; `wrangler dev` provides a local D1 for development, but a project whose primary consumer is not a Worker picks a different engine.
|
|
48
|
+
|
|
49
|
+
The blueprint round-2 ratification scoped persistence-data-d1 as the vendor sibling of persistence-data-sqlite on the shelf. The two blueprints ship the same two global topics on purpose (`persistenceStore` and `migrationDiscipline`) with different vendor answers. Composing both on one project surfaces the pairing as two `globalAdrTopic` conflicts the operator resolves; the expected shape is one project-level ADR per topic that fixes the tier reasoning. A project that mixes D1 for one deployable and single-file SQLite for another deployable does so through separate project-level ADR rulings, not through mixing both blueprints on one project.
|
|
50
|
+
|
|
51
|
+
## What a good outcome looks like
|
|
52
|
+
|
|
53
|
+
A project applies the persistence-data-d1 blueprint on a fresh tree, wires its own domain migration files into the wrangler-configured directory (starting at file number 0001), realises the four TACs in project-authored FBSes, wires the CI job with `wrangler d1 migrations apply` ordered strictly before `wrangler deploy`, and lands on a deployed Worker where:
|
|
54
|
+
|
|
55
|
+
- The first Worker request per isolate imports the facade, reads the D1 binding once from `env`, and serves the request; the facadeReady event fires exactly once per isolate with the binding and environment names.
|
|
56
|
+
- A schema change ships as a new numbered `.sql` file under the wrangler-configured directory; the next deploy's CI job applies the file to the target D1 database, the deploy proceeds, the migrationsApplied event fires with the applied filename, and consumer code reads through the facade at the new schema shape.
|
|
57
|
+
- An accidental drop is a one-command Time Travel restore inside the plan's recovery window; the timeTravelRestored event fires with the restore timestamp; a fresh Worker request reads the pre-drop state.
|
|
58
|
+
- A scheduled export runs on a cron against the live database; the backupExported event fires on the sink with the artifact path and the completion timestamp; a fresh D1 database primed from that artifact reads the rows committed at or before the export completion timestamp.
|
|
59
|
+
- A rollback to an older Worker build against a database whose migration set is ahead of the older build's expectations serves cleanly, because the older Worker's SQL literals target a schema shape that is a prefix of the current schema; the vendor's SQLite semantics let the older SELECTs and INSERTs ignore columns added in later migrations.
|
|
60
|
+
- The auth event log, the wire-request log, and every other domain log surface holds no store-lifecycle records; the store's event log holds no domain-row values, and a queryFailed event carries the domain-verb name plus the D1 error code, never the failed statement's parameter values.
|
|
61
|
+
|
|
62
|
+
## Operator decisions that remain open after apply
|
|
63
|
+
|
|
64
|
+
- Engine choice (D1 default, single-file SQLite for non-Workers deployables, or Postgres or KV-store by superseding ADR-1401 with a project-level ADR). Blueprint owns the facade contract on both sides of the boundary; project owns the engine.
|
|
65
|
+
- Migration file naming pattern (wrangler default numbered form, or an ORM-compatible pattern set on `migrations_pattern`). Blueprint owns the shape; project owns the pattern at the ORM alignment cost the project accepts.
|
|
66
|
+
- Binding name and database identifier (the wrangler config values). Blueprint owns the read shape (one binding, one facade); project owns the deployed values and how they are supplied per environment.
|
|
67
|
+
- Domain schema (every table the domain requires). Blueprint owns the migration discipline; project owns the tables.
|
|
68
|
+
- Export schedule and destination (cron cadence, artifact path template, retention, R2 bucket or repository asset choice). Blueprint owns the export runner and its event; project owns when and where.
|
|
69
|
+
- Restore drill cadence (a backup you have not restored is a hope, not a backup). Blueprint owns the artifact shape and the Time Travel restore command; project owns proving both work.
|
|
70
|
+
- Log sink implementation (where facadeReady, migrationsApplied, backupExported, timeTravelRestored, queryFailed events go). Blueprint owns the event shape and the metadata-only discipline; project owns the shipper.
|
|
71
|
+
- CI pipeline choice (GitHub Actions, GitLab CI, whatever). Blueprint owns the ordering contract on the migrations-apply-before-deploy sequence; project owns the CI tool that implements it.
|
|
72
|
+
- Facade verb catalogue (the named CRUD verbs the domain needs). Blueprint owns the boundary discipline (named verbs, prepared statements, batch atomicity, no raw-query passthrough); project owns the verbs.
|
|
73
|
+
- Secrets storage for the CI credential (`CLOUDFLARE_API_TOKEN` and any deploy-specific secret). Blueprint references the credential by role; the security-secrets-management blueprint owns storage and rotation.
|
|
74
|
+
|
|
75
|
+
## Cost-honesty paragraph
|
|
76
|
+
|
|
77
|
+
Shipping this doc set costs the project the following. Every deploy pipeline pays the migrations-apply latency (one wrangler invocation, one round trip to the D1 API) before the Worker deploy runs. Every facade verb is a project-authored function; the boundary discipline means new query shapes are a two-file edit (facade plus consumer) instead of a scattered raw SQL fragment. Every schema change is a numbered `.sql` file the project must not edit after shipping (a shipped migration is a fact of production; a correction is a new numbered file, applied on top). The deploy-gate ordering property makes a failed apply a red CI job rather than a customer-visible 5xx; that safety comes at the cost of a slower deploy loop on any migration change (the apply runs before the deploy; on rollback the operator ships the older code with a migration set that is a prefix, and the older SQL literals ignore added columns per SQLite semantics). Time Travel is the vendor's built-in fast path but bounded by the plan window (currently 30 days on Paid, 7 days on Free); a project whose compliance model demands longer retention runs the export step on a schedule and holds the artifacts off-vendor. The export path is slow enough that the vendor's own guidance warns it blocks other database requests for the duration; schedule it in low-traffic windows. The store's event log is deliberately minimal; a project that needs richer per-operation events (row-level audit trail, hot-path timing) authors those on top of the facade's verbs, not inside the store event sink. The prepared-statement discipline closes the SQL-injection surface by construction, at the cost that consumers who want to hand-roll a new query shape have to add a named verb to the facade instead of reaching into the binding directly.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Persistence blueprint (v1.0.0)
|
|
2
|
+
|
|
3
|
+
The fourth content blueprint on the rcf-build-lite blueprint mechanism (design brief v2, ratified; Phase 4 of the blueprint programme). Scope: single-file SQLite as the default durable store with a forward-only numbered migration catalog applied atomically at open, a store facade that is the sole boundary between the domain and the engine, a structured lifecycle event log, and a downtime-free file-level backup runner. Targeted at small greenfield rcf-lite projects. Postgres is a documented future variant behind the same facade; the v1.0.0 blueprint ships SQLite only.
|
|
4
|
+
|
|
5
|
+
## Apply
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
rcf define blueprint add <path-to>/blueprints/persistence-data-sqlite
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Phase 1 resolves local path sources only; registry and git-ref resolution is a mechanism follow-up. Apply is idempotent; `rcf define blueprint list` shows the applied entry; `rcf define blueprint remove persistence-data-sqlite` cleanly removes an unreferenced application.
|
|
12
|
+
|
|
13
|
+
## Anatomy
|
|
14
|
+
|
|
15
|
+
| Piece | Where | What |
|
|
16
|
+
|---|---|---|
|
|
17
|
+
| Metadata | `blueprint.json` | Slug, version, and the 31 contributions with scope/topic on the two global ADRs |
|
|
18
|
+
| Doc set | `contributions/` | 11 REQs, 11 USs (25 ACs), 4 TACs, 5 ADRs, all schema-valid against rcf-schemas 0.4.5 and namespaced (`persistence-data-sqlite-REQ-001` prefix family; `ADR-601-persistence-data-sqlite-store-model` suffix family) |
|
|
19
|
+
| Migration shape sample | `assets/schema-samples/migration-shape.md` | The exact shape of a migration catalog entry (version, description, statements) with a worked example |
|
|
20
|
+
| Catalog layout sample | `assets/schema-samples/catalog-file-layout.md` | Two layouts the catalog module can take (one file, one file per migration) with a pick guide |
|
|
21
|
+
| SQLite backup procedure | `assets/backup-procedures/sqlite-file-copy.md` | The downtime-free file-copy procedure under WAL, with the online-backup and checkpoint-then-copy paths |
|
|
22
|
+
| WAL checkpoint note | `assets/backup-procedures/hot-checkpoint-note.md` | Why a checkpoint before a bare cp works, and when the online-backup API is the safer path |
|
|
23
|
+
| Guide | `guide/persistence-data-sqlite.md` | Operator-facing: when to use it, when not, what stays your call, and the promotion signal for the future Postgres variant |
|
|
24
|
+
| Coordination vocabulary | `docs/topics.md` | The two global-topic strings this blueprint contributes, the shared id band registry (application-spa, application-api-rest, security-auth-magic-link, hello-panel, persistence-data-sqlite, ci-pipeline, observability-essentials) |
|
|
25
|
+
|
|
26
|
+
The doc set is contributions (copied into the project tree by `rcf define blueprint add`); the guide, assets, and docs are package-resident references. Guide rendering into `rcf/knowledge/docs/blueprint-guides/` and asset ingestion are mechanism follow-ups; until they land, the working agent reads them from the applied blueprint's source path recorded in `manifest.blueprints[].source`.
|
|
27
|
+
|
|
28
|
+
## What it contributes, and what it deliberately does not
|
|
29
|
+
|
|
30
|
+
Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (ratified decision 5) and no code.
|
|
31
|
+
|
|
32
|
+
No FBS contributions, as a matter of principle (ratified policy 2026-08-19): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT (the store facade contract, the migration runner contract, the migration catalog shape, the backup runner contract, the event log discipline); the implementing agent derives the HOW-tasks (FBS) in the host project, where the ACs contributed here get picked up by the project's own build sequencing.
|
|
33
|
+
|
|
34
|
+
Deliberately not contributed: the domain schema (the tables the project's own entities live in are project-authored, not blueprint-authored; the blueprint governs the store facade and the migration discipline, not the domain shape); ORMs, query builders, and any framework-shaped abstraction above the named CRUD verbs (the facade is a project-authored surface; how it internally implements its verbs is not blueprint-owned); a Postgres engine TAC (deferred; see ADR-601's alternatives and the guide 'when it does not fit'); logical schema-aware dumps (out of scope; see ADR-605's alternatives); connection pooling (an implementation detail of the facade when a project selects an engine that benefits from it, not a blueprint contribution).
|
|
35
|
+
|
|
36
|
+
## The two global decisions
|
|
37
|
+
|
|
38
|
+
ADR-601-persistence-data-sqlite-store-model ships `scope: global` on topic `persistenceStore`. This is the project's primary durable store engine choice: single SQLite file, WAL mode, one entry point through the facade. A composing blueprint that holds a different engine opinion (a Postgres-first blueprint, a KV-store blueprint, an event-sourced blueprint) conflicts here by design and expects a project-level ADR resolution.
|
|
39
|
+
|
|
40
|
+
ADR-602-persistence-data-sqlite-migration-discipline ships `scope: global` on topic `migrationDiscipline`. This is the project's schema-evolution posture: forward-only numbered migrations, atomic per-migration, refuse-newer-than-build at open. A composing blueprint that holds an opinion on migration discipline (event-sourced projections, bidirectional migrations, tenant-per-schema) conflicts here by design.
|
|
41
|
+
|
|
42
|
+
See `docs/topics.md` for the exact strings, the expected resolutions, the delineation from the application-api-rest blueprint's `logging` topic (which governs the wire-log shape, not the store-event log shape), and the AC id band allocation (persistence-data-sqlite owns 5101-5899).
|
|
43
|
+
|
|
44
|
+
## Quality bar
|
|
45
|
+
|
|
46
|
+
Single durable store opened via one boot-time entry point that runs migrations before returning; numbered forward-only migration catalog committed in-tree with a monotonic version integer per entry; refuse-newer-than-build at open with a stable error code naming both versions and no writes on that path; atomic per-migration transactions covering statements and the version bookkeeping row together; kill-9 tolerant durability posture (WAL plus synchronous commit floor under SQLite; engine-native equivalent otherwise) set at open by the facade; structured event log at four defined moments (opened, migrated, backupCheckpoint, closed) with metadata-only fields; store facade as the sole importer of the engine binding, exposing named domain verbs with no raw-query passthrough on the public surface; downtime-free file-level backup emitting a checkpoint event with artifact path and completion timestamp; migration-failed error naming the failing version and preserving the previous version on disk; no domain-row values on the event sink; idempotent no-op open when the store is already at target version. Every bar is carried by ACs in the doc set, not by this README.
|
|
47
|
+
|
|
48
|
+
## Known mechanism-reach gaps
|
|
49
|
+
|
|
50
|
+
None at v1.0.0. Every AC on every story is bound to at least one TAC that the host project must realise, and every AC's `then` clause is runtime-observable in the deployed application (event-log record inspection, store-artifact snapshot comparison, engine-native introspection queries through the facade, source-tree import-graph queries for the boundary properties). The mechanism-reach principle from the authoring standard section 7 is satisfied at ship: a project that applies this blueprint and does not realise a TAC leaves an unresolved `tacIds` reference on the story that `rcf define validate` and `rcf audit coverage` refuse. The one operational responsibility a project must own on its own is the engine choice itself, if it supersedes ADR-601 with a project-level ADR; that responsibility is stated as an ADR alternative (see ADR-601 and the guide 'when it does not fit'), not as a smuggled runtime probe.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Why the checkpoint-then-copy path works, and when to prefer online-backup
|
|
2
|
+
|
|
3
|
+
## The setup
|
|
4
|
+
|
|
5
|
+
Under SQLite in WAL mode (ADR-601's default posture), committed writes land in a write-ahead log file (`<db>-wal`) and are periodically checkpointed into the main database file. Readers see committed writes across both the main file and the WAL; a bare `cp` of the main file captures only the pre-checkpoint state and can miss recent committed writes.
|
|
6
|
+
|
|
7
|
+
## Why the checkpoint fixes it
|
|
8
|
+
|
|
9
|
+
`PRAGMA wal_checkpoint(TRUNCATE)` forces every committed WAL page into the main file and truncates the WAL. After the checkpoint, the main file alone holds every committed write as of the checkpoint moment; a subsequent `cp` captures a consistent snapshot as of that moment. Writers on the source connection stay available: writes committed after the checkpoint land in a new WAL segment and are outside the artifact (which is the intended semantics: the artifact is a snapshot as of the checkpoint, not as of the `cp` completion).
|
|
10
|
+
|
|
11
|
+
## Why online-backup is still preferred
|
|
12
|
+
|
|
13
|
+
Two properties online-backup gives that checkpoint-then-copy does not:
|
|
14
|
+
|
|
15
|
+
- **Streaming rather than dual-storage.** The online-backup API streams pages to the destination without materialising the main file at a specific moment; for a large store, checkpointing everything into the main file at once is an operator-visible I/O spike.
|
|
16
|
+
- **No writer blocking on the checkpoint call.** `PRAGMA wal_checkpoint(TRUNCATE)` waits for readers to release the WAL; on a busy store this can pause the writer for the duration of the wait. Online-backup does not have this pause.
|
|
17
|
+
|
|
18
|
+
For rcf-lite-tier stores (small working sets, one host, human-scale write rate) the difference is not operator-visible and either path is defensible. Bindings that expose online-backup cleanly (node:sqlite, better-sqlite3) should use it; bindings that don't (older builds, unusual environments) use checkpoint-then-copy without apology.
|
|
19
|
+
|
|
20
|
+
## What breaks if you skip the checkpoint
|
|
21
|
+
|
|
22
|
+
A bare `cp` of a WAL-mode SQLite file without checkpointing produces an artifact that is missing every committed write in the WAL at copy time. On restore the missing writes are gone. This is the failure mode ADR-605's alternatives paragraph refers to: the operator sees a backup file that opens cleanly and reports the right schema version but is missing an unpredictable tail of recent writes. The runner never takes this path; the checkpoint-then-copy path in `sqlite-file-copy.md` is the fallback the runner uses when online-backup is not available.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# SQLite backup procedure (default engine, ADR-601 + ADR-605)
|
|
2
|
+
|
|
3
|
+
The backup runner (TAC-604) produces a self-contained artifact without downtime. Under SQLite in WAL mode (the default engine), two paths satisfy the AC-5108-1 downtime-free property; pick the one the project's SQLite binding supports cleanly.
|
|
4
|
+
|
|
5
|
+
## Path 1: online-backup API (preferred)
|
|
6
|
+
|
|
7
|
+
The SQLite online-backup API opens a second connection in backup mode and streams pages from the source to the destination file. Writers on the source connection stay available for the full duration; the copy is transactionally consistent at the point the API completes.
|
|
8
|
+
|
|
9
|
+
```javascript
|
|
10
|
+
// Inside TAC-604's backup implementation, using the node:sqlite binding.
|
|
11
|
+
import { DatabaseSync } from 'node:sqlite';
|
|
12
|
+
|
|
13
|
+
export async function backup(sourceDb, outputPath) {
|
|
14
|
+
const dest = new DatabaseSync(outputPath);
|
|
15
|
+
try {
|
|
16
|
+
// Bindings vary in shape; the essence is 'open a backup handle from
|
|
17
|
+
// source to dest and step it to completion'. node:sqlite exposes
|
|
18
|
+
// sourceDb.backup(dest); some bindings require .step(-1) loops.
|
|
19
|
+
await sourceDb.backup(dest);
|
|
20
|
+
return {
|
|
21
|
+
artifactPath: outputPath,
|
|
22
|
+
completedAt: new Date().toISOString(),
|
|
23
|
+
};
|
|
24
|
+
} finally {
|
|
25
|
+
dest.close();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Emit the `backupCheckpoint` event on the store's event sink at completion (AC-5108-3), carrying `{ event: 'backupCheckpoint', ts, artifactPath, completedAt }`.
|
|
31
|
+
|
|
32
|
+
## Path 2: checkpoint-then-copy
|
|
33
|
+
|
|
34
|
+
For bindings that do not expose the online-backup API, a WAL checkpoint followed by a filesystem-level copy of the main file is a defensible fallback. The checkpoint flushes all committed WAL pages into the main file; the copy captures every committed write as of the checkpoint moment. Writers on the source connection stay available; concurrent writes after the checkpoint land in a new WAL segment and are not in the artifact (which is the intended semantics: the artifact is a snapshot as-of the checkpoint).
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
// Inside TAC-604's backup implementation.
|
|
38
|
+
import { copyFile } from 'node:fs/promises';
|
|
39
|
+
|
|
40
|
+
export async function backup(sourceDb, sourcePath, outputPath) {
|
|
41
|
+
sourceDb.exec('PRAGMA wal_checkpoint(TRUNCATE)');
|
|
42
|
+
await copyFile(sourcePath, outputPath);
|
|
43
|
+
return {
|
|
44
|
+
artifactPath: outputPath,
|
|
45
|
+
completedAt: new Date().toISOString(),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Emit the `backupCheckpoint` event as above.
|
|
51
|
+
|
|
52
|
+
## Recovery
|
|
53
|
+
|
|
54
|
+
Recovery is opening the artifact through the store facade against a compatible build:
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
cp backup.sqlite /path/to/deployed/store.sqlite
|
|
58
|
+
# restart the process; facade openStore({ path: '/path/to/deployed/store.sqlite' })
|
|
59
|
+
# runs, opened event fires, schemaVersion matches the artifact's version
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The refuse-newer property (AC-5103-1) applies here: recovering a newer-than-build artifact under an older build fails at boot; the fix is to recover under a build at or ahead of the artifact's schema version.
|
|
63
|
+
|
|
64
|
+
## What this procedure is not
|
|
65
|
+
|
|
66
|
+
Not a logical dump. The artifact is a SQLite file, not a portable SQL script; a project that needs cross-engine restore layers a project-authored dump runner beside this one (see ADR-605's alternatives).
|
|
67
|
+
|
|
68
|
+
Not a replication story. Cross-region replication is engine-native (SQLite Litestream or the alternate engine ADR-601 is superseded to); the backup runner produces one artifact per invocation and does not orchestrate shipping.
|
|
69
|
+
|
|
70
|
+
Not a retention manager. The artifact filename and the delete-old-artifacts cadence are project concerns; the runner writes the artifact and emits the checkpoint event.
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# Migration catalog layout
|
|
2
|
+
|
|
3
|
+
The catalog exports `MIGRATIONS` (the ordered array) and `CURRENT_VERSION` (the max version integer). Two layouts satisfy TAC-603; pick one at project start and stay with it.
|
|
4
|
+
|
|
5
|
+
## Layout A: one file (recommended up to ~30 entries)
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
src/store/
|
|
9
|
+
schema.js // exports MIGRATIONS array and CURRENT_VERSION
|
|
10
|
+
store.js // the facade (TAC-601)
|
|
11
|
+
migrationRunner.js // the runner (TAC-602)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`src/store/schema.js`:
|
|
15
|
+
|
|
16
|
+
```javascript
|
|
17
|
+
export const MIGRATIONS = [
|
|
18
|
+
{ version: 1, description: '...', statements: ['...'] },
|
|
19
|
+
{ version: 2, description: '...', statements: ['...'] },
|
|
20
|
+
// ... more entries appended over the project's history
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
export const CURRENT_VERSION = MIGRATIONS[MIGRATIONS.length - 1].version;
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Pros: every version is visible on one screen; grep for a table name lands on the migration that created and every migration that altered it; PR review of a schema change is one file.
|
|
27
|
+
|
|
28
|
+
Cons: file size grows with history; large teams may see merge conflicts on the array-tail append.
|
|
29
|
+
|
|
30
|
+
## Layout B: one file per migration (recommended past ~30 entries)
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
src/store/
|
|
34
|
+
schema.js // aggregates the migrations directory into MIGRATIONS + CURRENT_VERSION
|
|
35
|
+
migrations/
|
|
36
|
+
001-initial-schema.js
|
|
37
|
+
002-soft-delete-column.js
|
|
38
|
+
003-boot-markers.js
|
|
39
|
+
004-notifier-schema.js
|
|
40
|
+
// ... one file per migration
|
|
41
|
+
store.js
|
|
42
|
+
migrationRunner.js
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Each migration file:
|
|
46
|
+
|
|
47
|
+
```javascript
|
|
48
|
+
// src/store/migrations/002-soft-delete-column.js
|
|
49
|
+
export default {
|
|
50
|
+
version: 2,
|
|
51
|
+
description: 'soft-delete: entityA.removedAt column',
|
|
52
|
+
statements: [`ALTER TABLE entityA ADD COLUMN removedAt TEXT`],
|
|
53
|
+
};
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
`src/store/schema.js` aggregates:
|
|
57
|
+
|
|
58
|
+
```javascript
|
|
59
|
+
import migration001 from './migrations/001-initial-schema.js';
|
|
60
|
+
import migration002 from './migrations/002-soft-delete-column.js';
|
|
61
|
+
// ... one import per migration file
|
|
62
|
+
|
|
63
|
+
export const MIGRATIONS = [migration001, migration002, /* ... */];
|
|
64
|
+
export const CURRENT_VERSION = MIGRATIONS[MIGRATIONS.length - 1].version;
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Pros: one migration is one file; PR review is a fresh file, not an array edit; merge conflicts are structurally rare (contributors touch different filenames).
|
|
68
|
+
|
|
69
|
+
Cons: two-file edit per new migration; grep for a table name lands on multiple files; version integers appear in filenames and in the file body and must agree.
|
|
70
|
+
|
|
71
|
+
## Migration between layouts
|
|
72
|
+
|
|
73
|
+
Layout A converts to Layout B by extracting each array entry into a numbered file and rewriting `schema.js` to aggregate. The exported names (`MIGRATIONS`, `CURRENT_VERSION`) stay identical, so the runner and the facade do not change. Do the conversion in a single commit with no logical schema change.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Migration entry shape
|
|
2
|
+
|
|
3
|
+
Every entry in the migration catalog (TAC-603) has this exact shape:
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
{
|
|
7
|
+
version: <integer>, // monotonic, starts at 1, no gaps
|
|
8
|
+
description: <string>, // human-readable; ships in the migration-failed error
|
|
9
|
+
statements: [<string>, ...] // one or more engine-native DDL/data statements
|
|
10
|
+
}
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The `statements` list executes inside one transaction opened by the migration runner (TAC-602); the version bookkeeping row inserts inside the same transaction. On any failure, the transaction rolls back and the on-disk version reflects the last successfully committed migration.
|
|
14
|
+
|
|
15
|
+
## Worked example
|
|
16
|
+
|
|
17
|
+
A four-migration catalog starting with an eleven-table initial schema, followed by a soft-delete column, a boot marker, and a notifier-schema expansion. Statements are SQLite dialect at the default engine (ADR-601); the shape is identical under any alternate engine ADR-601 is superseded to.
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
export const MIGRATIONS = [
|
|
21
|
+
{
|
|
22
|
+
version: 1,
|
|
23
|
+
description: 'initial schema, eleven entities',
|
|
24
|
+
statements: [
|
|
25
|
+
`CREATE TABLE schemaVersion (
|
|
26
|
+
version INTEGER PRIMARY KEY,
|
|
27
|
+
appliedAt TEXT NOT NULL
|
|
28
|
+
)`,
|
|
29
|
+
`CREATE TABLE entityA (
|
|
30
|
+
id TEXT PRIMARY KEY,
|
|
31
|
+
name TEXT NOT NULL UNIQUE,
|
|
32
|
+
createdAt TEXT NOT NULL,
|
|
33
|
+
updatedAt TEXT NOT NULL
|
|
34
|
+
)`,
|
|
35
|
+
// ... nine more CREATE TABLE statements per the initial schema
|
|
36
|
+
],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
version: 2,
|
|
40
|
+
description: 'soft-delete: entityA.removedAt column for file-lane removal without eager history loss',
|
|
41
|
+
statements: [
|
|
42
|
+
`ALTER TABLE entityA ADD COLUMN removedAt TEXT`,
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
version: 3,
|
|
47
|
+
description: 'boot markers: audit trail of process starts for honest-gap accounting',
|
|
48
|
+
statements: [
|
|
49
|
+
`CREATE TABLE bootMarker (
|
|
50
|
+
bootAt TEXT PRIMARY KEY
|
|
51
|
+
)`,
|
|
52
|
+
],
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
version: 4,
|
|
56
|
+
description: 'notifier: per-entity channel routes and pending-delivery resume queue',
|
|
57
|
+
statements: [
|
|
58
|
+
`CREATE TABLE entityChannelRoute (
|
|
59
|
+
entityId TEXT NOT NULL,
|
|
60
|
+
channelId TEXT NOT NULL,
|
|
61
|
+
PRIMARY KEY (entityId, channelId)
|
|
62
|
+
)`,
|
|
63
|
+
`ALTER TABLE channel ADD COLUMN isDefault INTEGER NOT NULL DEFAULT 0`,
|
|
64
|
+
],
|
|
65
|
+
},
|
|
66
|
+
];
|
|
67
|
+
|
|
68
|
+
export const CURRENT_VERSION = MIGRATIONS[MIGRATIONS.length - 1].version;
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Rules a project must not break
|
|
72
|
+
|
|
73
|
+
- **Version integers are monotonic and start at 1 with no gaps.** A missing version between shipped entries breaks the ordering guarantee the runner relies on. Two contributors landing overlapping versions is a merge conflict, not a runtime bug.
|
|
74
|
+
- **A shipped migration is never edited.** Adding a statement to an already-shipped entry is a silent schema divergence between production stores at different open cycles. Fixes ship as new numbered migrations.
|
|
75
|
+
- **The statements list is engine-native.** Dialect matches the engine selected in ADR-601 (or its superseding project ADR). Statements are strings, not query builders; the runner does not interpret them.
|
|
76
|
+
- **The bookkeeping insert is the runner's responsibility, not the migration's.** A migration whose statements include an `INSERT INTO schemaVersion` corrupts the runner's ordering; the runner already handles that insert inside the same transaction.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
{
|
|
2
|
+
"slug": "persistence-data-sqlite",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"category": "persistence",
|
|
5
|
+
"contributions": [
|
|
6
|
+
{ "id": "persistence-data-sqlite-REQ-001", "kind": "req", "path": "requirements/persistence-data-sqlite-req-001.json" },
|
|
7
|
+
{ "id": "persistence-data-sqlite-REQ-002", "kind": "req", "path": "requirements/persistence-data-sqlite-req-002.json" },
|
|
8
|
+
{ "id": "persistence-data-sqlite-REQ-003", "kind": "req", "path": "requirements/persistence-data-sqlite-req-003.json" },
|
|
9
|
+
{ "id": "persistence-data-sqlite-REQ-004", "kind": "req", "path": "requirements/persistence-data-sqlite-req-004.json" },
|
|
10
|
+
{ "id": "persistence-data-sqlite-REQ-005", "kind": "req", "path": "requirements/persistence-data-sqlite-req-005.json" },
|
|
11
|
+
{ "id": "persistence-data-sqlite-REQ-006", "kind": "req", "path": "requirements/persistence-data-sqlite-req-006.json" },
|
|
12
|
+
{ "id": "persistence-data-sqlite-REQ-007", "kind": "req", "path": "requirements/persistence-data-sqlite-req-007.json" },
|
|
13
|
+
{ "id": "persistence-data-sqlite-REQ-008", "kind": "req", "path": "requirements/persistence-data-sqlite-req-008.json" },
|
|
14
|
+
{ "id": "persistence-data-sqlite-REQ-009", "kind": "req", "path": "requirements/persistence-data-sqlite-req-009.json" },
|
|
15
|
+
{ "id": "persistence-data-sqlite-REQ-010", "kind": "req", "path": "requirements/persistence-data-sqlite-req-010.json" },
|
|
16
|
+
{ "id": "persistence-data-sqlite-REQ-011", "kind": "req", "path": "requirements/persistence-data-sqlite-req-011.json" },
|
|
17
|
+
{ "id": "persistence-data-sqlite-US-5101", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5101.json" },
|
|
18
|
+
{ "id": "persistence-data-sqlite-US-5102", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5102.json" },
|
|
19
|
+
{ "id": "persistence-data-sqlite-US-5103", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5103.json" },
|
|
20
|
+
{ "id": "persistence-data-sqlite-US-5104", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5104.json" },
|
|
21
|
+
{ "id": "persistence-data-sqlite-US-5105", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5105.json" },
|
|
22
|
+
{ "id": "persistence-data-sqlite-US-5106", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5106.json" },
|
|
23
|
+
{ "id": "persistence-data-sqlite-US-5107", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5107.json" },
|
|
24
|
+
{ "id": "persistence-data-sqlite-US-5108", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5108.json" },
|
|
25
|
+
{ "id": "persistence-data-sqlite-US-5109", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5109.json" },
|
|
26
|
+
{ "id": "persistence-data-sqlite-US-5110", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5110.json" },
|
|
27
|
+
{ "id": "persistence-data-sqlite-US-5111", "kind": "us", "path": "user-stories/persistence-data-sqlite-us-5111.json" },
|
|
28
|
+
{ "id": "TAC-601-persistence-data-sqlite-store", "kind": "tac", "path": "tacs/tac-601-persistence-data-sqlite-store.json" },
|
|
29
|
+
{ "id": "TAC-602-persistence-data-sqlite-migration-runner", "kind": "tac", "path": "tacs/tac-602-persistence-data-sqlite-migration-runner.json" },
|
|
30
|
+
{ "id": "TAC-603-persistence-data-sqlite-migration-catalog", "kind": "tac", "path": "tacs/tac-603-persistence-data-sqlite-migration-catalog.json" },
|
|
31
|
+
{ "id": "TAC-604-persistence-data-sqlite-backup-runner", "kind": "tac", "path": "tacs/tac-604-persistence-data-sqlite-backup-runner.json" },
|
|
32
|
+
{
|
|
33
|
+
"id": "ADR-601-persistence-data-sqlite-store-model",
|
|
34
|
+
"kind": "adr",
|
|
35
|
+
"path": "adrs/adr-601-persistence-data-sqlite-store-model.json",
|
|
36
|
+
"scope": "global",
|
|
37
|
+
"topic": "persistenceStore"
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"id": "ADR-602-persistence-data-sqlite-migration-discipline",
|
|
41
|
+
"kind": "adr",
|
|
42
|
+
"path": "adrs/adr-602-persistence-data-sqlite-migration-discipline.json",
|
|
43
|
+
"scope": "global",
|
|
44
|
+
"topic": "migrationDiscipline"
|
|
45
|
+
},
|
|
46
|
+
{ "id": "ADR-603-persistence-data-sqlite-event-secrecy", "kind": "adr", "path": "adrs/adr-603-persistence-data-sqlite-event-secrecy.json" },
|
|
47
|
+
{ "id": "ADR-604-persistence-data-sqlite-store-boundary", "kind": "adr", "path": "adrs/adr-604-persistence-data-sqlite-store-boundary.json" },
|
|
48
|
+
{ "id": "ADR-605-persistence-data-sqlite-backup-model", "kind": "adr", "path": "adrs/adr-605-persistence-data-sqlite-backup-model.json" }
|
|
49
|
+
]
|
|
50
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-601-persistence-data-sqlite-store-model",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Single SQLite file with WAL-mode crash safety as the project's default durable store; Postgres as a documented future variant",
|
|
8
|
+
"context": "A project has one primary durable store: the substrate every domain entity lives in and every domain query resolves against. Choice of engine sets the crash-safety story, the backup story, the deploy story, the ops footprint, and the scale ceiling. The rcf-lite tier this blueprint targets is small single-deployable greenfield: one team, one host or one small container fleet, no ops team standing by. That tier has a natural answer.",
|
|
9
|
+
"decision": "The default primary durable store is a single SQLite file opened in WAL journal mode with synchronous=NORMAL, foreign_keys=ON, accessed through the store facade (TAC-601) which is the only module that imports the SQLite binding. One file per deployed instance; the file path is a configuration input to the open entry point; backups are file-level snapshots taken through the backup runner (TAC-604) without downtime; migrations are numbered forward-only entries in the in-tree catalog (TAC-603) applied at open by the runner (TAC-602). Postgres is a documented future variant behind the same facade: a project that outgrows SQLite supersedes this ADR with a project-level ADR selecting the alternate engine, replaces the facade's engine binding, and rewrites the migration catalog into the alternate dialect. The blueprint mechanism does not ship a Postgres variant as an alternate contribution at v1.0.0 because the mechanism has no variant/profile selector: two engine TACs contributed together would both need realising or both leave dangling references. One default plus a documented promotion path is the shape that fits the mechanism today.",
|
|
10
|
+
"consequences": "The project inherits zero-infrastructure persistence: no database server, no connection pool, no network round trip; the store is a file on the same host the process runs on. Backups are file copies. Deploys move the file with the container image or with the volume mount. Kill-9 tolerance is a WAL property, not a hand-rolled invariant. The scale ceiling is a single-writer envelope: multi-writer workloads and cross-host replication are out of reach without switching engines, and the promotion signal is real (see guide 'when it does not fit'). Composing blueprints that hold an opinion on the store engine conflict on the persistenceStore topic; the expected resolution is one project-level ADR that fixes the engine and states the reasoning for the tier, superseding this ADR and any composing blueprint's contribution.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Ship Postgres as a co-contributed alternate engine TAC alongside SQLite in v1.0.0",
|
|
14
|
+
"summary": "The blueprint contributes TAC-601-sqlite-store and TAC-601-postgres-store side by side; the project picks one at apply time.",
|
|
15
|
+
"reasonNotChosen": "The rcf-lite blueprint mechanism (Phase 1) has no variant/profile selector. Two TACs contributed together are both applied, and both leave dangling tacIds references on their user stories if the project only realises one. Adding a mechanism-level variant concept is a v1.1 investment; deferring the second engine to a superseding project-level ADR keeps v1.0.0 shippable and mirrors the security-auth-magic-link blueprint's keycloak-local deferral (see the auth guide 'when it does not fit')."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Postgres-first with SQLite as a test-only shim",
|
|
19
|
+
"summary": "Default to Postgres for production and offer SQLite as an ephemeral engine for tests.",
|
|
20
|
+
"reasonNotChosen": "Wrong shape for the tier. A single-deployable rcf-lite project should not carry a database server as a hard dependency at v1. Test-only in-memory doubles satisfy the test story more cheaply than a schema-mirrored SQLite for a Postgres deployment, at the cost of test fidelity that projects can trade explicitly."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Schema-agnostic KV store (RocksDB, LMDB)",
|
|
24
|
+
"summary": "Drop the relational shape and use a byte-oriented KV store as the substrate.",
|
|
25
|
+
"reasonNotChosen": "The relational shape is what makes the query story sane for the domain the rcf-lite tier typically ships. A KV substrate pushes the query problem into application code and gives up the constraint-checking safety net that SQLite provides for free. Projects whose domain is genuinely KV-shaped (opaque blob storage, event streams) supersede this ADR."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"createdAt": "2026-08-21T00:00:00Z",
|
|
29
|
+
"updatedAt": "2026-08-21T00:00:00Z"
|
|
30
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-602-persistence-data-sqlite-migration-discipline",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Forward-only numbered migrations applied atomically at open; refuse to boot against a store newer than the build",
|
|
8
|
+
"context": "Schema evolution in a running system has three failure modes: silent drift (the deployed schema does not match the code's assumptions), half-application (a migration ran partway and left the store in an undefined shape), and reverse-compatibility hazard (an older build opens a newer store and reads through unknown columns). The migration story has to close all three at the substrate level; asking every future contributor to hand-implement the discipline is the shape that produces the incident.",
|
|
9
|
+
"decision": "Schema evolution is a forward-only numbered migration catalog. Each migration entry carries a monotonic version integer, a description string, and one or more DDL/data statements. The migration runner (TAC-602) applies pending entries in ascending order at store open; each entry runs inside one transaction whose scope covers every statement plus the version bookkeeping insert. A per-migration failure rolls back the transaction, throws a migration-failed error naming the failing version, and does not attempt later entries. When the on-disk highest version is strictly greater than the catalog's max, the runner throws a refuse-newer error with a stable code and does not open the store. There are no down migrations: a rollback to an older schema is a redeploy against the older build, and the newer store refuses to open under the older build (that refusal is the safety property).",
|
|
10
|
+
"consequences": "Deploys are reproducible from a git ref because the catalog and the code that opens the store ship in one commit. Half-migrations are structurally impossible: a mid-migration crash rolls back the transaction and the on-disk version remains the last successfully committed one. Reverse-compatibility incidents fail loudly at boot instead of silently at the first read. The cost is that a botched schema change is a code fix and a redeploy, not a schema-side undo: projects that need to revert a migration in-place cannot, and must instead ship a compensating forward migration under a new version. Composing blueprints that hold their own opinion on migration discipline (event-sourced projections, dual-write patterns, tenant-per-schema) conflict on the migrationDiscipline topic; the expected resolution is one project-level ADR that fixes the discipline for the project.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Bidirectional up/down migrations",
|
|
14
|
+
"summary": "Every migration ships an up statement set and a down statement set; the runner supports rolling back to an older version by executing the down statements in reverse order.",
|
|
15
|
+
"reasonNotChosen": "Down migrations are notoriously wrong (contributors write them from imagination, not from testing, and the first time they run in anger is when they are needed). The refuse-newer property gives the safety a down migration is supposed to give (older code cannot damage a newer store), without the maintenance cost of a shipping-and-testing down path that is exercised approximately never."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Best-effort tolerant reads under an older build",
|
|
19
|
+
"summary": "The older build opens the newer store, ignores unknown columns, and serves reads it can express.",
|
|
20
|
+
"reasonNotChosen": "The failure mode is silent data damage on writes: an INSERT that does not name a NOT NULL column added in the newer schema fails at the engine, and an UPDATE that overwrites structured data with the older shape corrupts the newer data. Refuse-at-boot is the only reliable posture; the operator sees the error at deploy time rather than at 03:00 when a customer notices."
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
"name": "Migrations run through an external tool (e.g. Flyway, Alembic) invoked out-of-band at deploy",
|
|
24
|
+
"summary": "The store code assumes the schema is already at the right version; a deploy step external to the process runs the migrations.",
|
|
25
|
+
"reasonNotChosen": "Adds a moving part to the deploy pipeline and to the ops runbook, decouples the migration-run success signal from the process-start success signal, and introduces the possibility of a process starting against a store the migrations have not been run on. Running migrations at open ties the two success signals together and makes the process refuse to start on any deploy that skipped the migration step."
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"createdAt": "2026-08-21T00:00:00Z",
|
|
29
|
+
"updatedAt": "2026-08-21T00:00:00Z"
|
|
30
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-603-persistence-data-sqlite-event-secrecy",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Store event fields are restricted to store metadata; no domain-row values reach the event sink",
|
|
8
|
+
"context": "The store's event log describes the store's own lifecycle (opened, migrated, backupCheckpoint, closed). The store also holds the domain's most sensitive material: session handles, token secrets, credential material, private keys, whatever the project stores. Conflating the two produces a log stream that a downstream observability provider cannot be trusted with, and that a log-store breach turns into a domain-data breach. The store's log shape is distinct from the application-api-rest tier's wire-log shape (topic 'logging', owned by the application-api-rest blueprint's ADR-304): this ADR governs the store event surface only.",
|
|
9
|
+
"decision": "Every field on every store event is restricted to store metadata: the event name string, an ISO-8601 timestamp, the store identifier (path or connection string), schema version integers, migration version integers, migration description strings, applied-version arrays, and backup artifact paths. No event field is populated with a value read from a domain row; no event field is populated with a value derived from a domain-row column marked as secret. The discipline is enforced at emit time inside the store facade (TAC-601) and the backup runner (TAC-604); the sink is treated as though it ships every field to a third-party observability provider by default. Downstream redaction is not relied on.",
|
|
10
|
+
"consequences": "The store's event log is safe to ship to any observability provider the operator picks; no per-provider redaction rule is negotiated. A log-store breach exposes lifecycle metadata (when did the store open, what version did it migrate through, when did the last snapshot land) but no domain data. Operators who need per-request correlation between the store's events and the domain surface derive a correlation id from something other than a row value (the request id is the intended surface). The REST tier's own log shape (ADR-304, wire logs) governs its own field set; the two logs may share a shipper but do not share this ADR's rules.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Emit domain-row values inside store events under a downstream redaction rule",
|
|
14
|
+
"summary": "Ship rich events with domain context and rely on a log-shipper redactor to strip secret fields.",
|
|
15
|
+
"reasonNotChosen": "Redactors miss cases (new field, misspelled field, escaped value in a nested structure), and the log is already on disk on the emitting host by the time the redactor runs. Not-emitting-at-source is the only reliable posture."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Hashed domain values in event fields",
|
|
19
|
+
"summary": "Emit a stable hash of the value so investigations can correlate without exposing the plaintext.",
|
|
20
|
+
"reasonNotChosen": "A hashed handle still lets an attacker with log access confirm 'this handle is the handle for that principal', which is enough for correlation attacks. The request id already provides the correlation surface without leaking anything, and no store-lifecycle event has a use case for domain-row correlation."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-21T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-21T00:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-604-persistence-data-sqlite-store-boundary",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "The store facade is the only module that imports the engine binding; consumers use named domain verbs, not raw queries",
|
|
8
|
+
"context": "A persistence boundary that leaks (the domain code imports the engine binding, or the facade exposes a general-purpose raw-query passthrough) is a boundary the swap-out story does not work through, the test-double story does not work through, and the reasoning-about-persistence-code-paths story does not work through. Every one of those benefits depends on the boundary being narrow at the point of consumption, not merely intended to be narrow.",
|
|
9
|
+
"decision": "One module (the store facade, TAC-601) imports the engine binding for the engine chosen in ADR-601. Every other module in the source tree that touches persistence imports the store facade and calls its named verbs. The facade's public surface exposes named domain verbs (insertX, findX, updateX, deleteX and the domain equivalents) with typed parameters; it does not expose a general-purpose query method whose parameter is a raw SQL string or an engine-native query object supplied by consumer code. When a consumer needs a query the facade does not currently express, the fix is to add a named verb to the facade, not to bypass the facade with a raw query.",
|
|
10
|
+
"consequences": "The engine choice is swappable because there is exactly one place that changes. Domain tests run against an in-memory double that implements the same verb surface, without importing the engine binding at any point in the test's call path. Every persistence code path is discoverable by grepping for the facade's exports. Consumers pay a small cost when they need a new query shape (a facade edit and a consumer edit, in one commit); the size of that cost is the mechanism enforcing the boundary. Composing blueprints that contribute persistence-adjacent components (a cache, an outbox, a projection) contribute their own facade modules on the same discipline; every one of them imports the store facade for its persistence needs, not the engine binding.",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "General-purpose raw-query passthrough on the facade",
|
|
14
|
+
"summary": "The facade exposes execute(sql, params) that consumers use for ad-hoc queries the facade does not otherwise express.",
|
|
15
|
+
"reasonNotChosen": "Any raw-query passthrough migrates over time from 'occasional escape hatch' to 'the way consumers write queries'. Every such call site is a code path that has to be re-audited on an engine swap, a code path that cannot be tested against an in-memory double, and a code path where the reasoning about the store's shape lives in string literals scattered across the codebase. The escape hatch is not worth the boundary erosion."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Domain-code direct engine imports for hot-path queries",
|
|
19
|
+
"summary": "Performance-sensitive queries import the engine binding directly and skip the facade.",
|
|
20
|
+
"reasonNotChosen": "Performance is not a defensible reason to erode the boundary at the rcf-lite tier: the facade adds no measurable overhead over the engine binding, and hot-path queries that genuinely need it are a rare-enough case to justify a specialised facade verb rather than an import-graph shortcut. Projects that outgrow the tier and need a different posture do so by superseding this ADR with reasoning."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-21T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-21T00:00:00Z"
|
|
25
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"adrId": "ADR-605-persistence-data-sqlite-backup-model",
|
|
3
|
+
"prdId": "PRD-001",
|
|
4
|
+
"tadId": "TAD-001",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "accepted",
|
|
7
|
+
"title": "Backup is a file-level snapshot of the store artifact taken without downtime",
|
|
8
|
+
"context": "A backup story has three axes: what the artifact is (a file, a logical dump, a stream), when it can run (with the application quiesced, with the application live), and how it recovers (point a build at the artifact, run a restore tool). For the rcf-lite tier with the SQLite default engine and the store-facade boundary, the file-level snapshot is the natural answer: the engine already writes the store as one file, the WAL posture already tolerates concurrent snapshot, and recovery is 'point a compatible build at the file'.",
|
|
9
|
+
"decision": "The backup runner (TAC-604) snapshots the store to a portable artifact while the application keeps serving reads and writes. Under the SQLite default engine, the runner uses the online-backup API or a WAL-checkpoint-then-file-copy; the writer connection stays available. The artifact is engine-native: a SQLite file, not a schema-agnostic dump. Recovery is opening the artifact through the same store facade against a compatible build. A backupCheckpoint event fires on completion carrying the artifact path and the ISO-8601 completion timestamp. Cross-engine migration (a SQLite backup restored into Postgres) is out of scope for this blueprint; projects that need it author a project-side logical-dump runner beside this one, and the file-level runner remains the primary recovery path.",
|
|
10
|
+
"consequences": "The backup story is cheap to run and cheap to test: a scheduler invokes store.backup(outputPath) on a cron, the operator inspects the backupCheckpoint event stream for freshness, and a recovery exercise is opening a copied file with the same build. No maintenance window is planned; no ops-side backup daemon is deployed. The cost is that the artifact is engine-native: switching engines is not restore-and-go, and a project that needs a portable dump does so on top of the file-level story. Projects that need cross-region replication supersede this ADR with an engine-native replication decision (SQLite Litestream, Postgres physical replication, or the engine promoted by ADR-601).",
|
|
11
|
+
"alternativesConsidered": [
|
|
12
|
+
{
|
|
13
|
+
"name": "Logical schema-aware dump as the primary backup",
|
|
14
|
+
"summary": "The backup runner produces a SQL script that recreates the schema and the rows; recovery replays the script.",
|
|
15
|
+
"reasonNotChosen": "Logical dumps are portable but slow on the write path (encoding every value as SQL) and slow on the recovery path (replaying every statement). For the rcf-lite tier the size and frequency of backups make the portability trade uneconomic. Projects that need portability author a logical dump runner beside the file-level one, kept in sync by the schema catalog."
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"name": "Quiesce-and-copy (planned downtime for backup)",
|
|
19
|
+
"summary": "The application takes a maintenance window; the backup runner copies the file with no writers active.",
|
|
20
|
+
"reasonNotChosen": "Any backup story that requires downtime is a backup story the operator skips. The engine's online-backup posture makes the downtime unnecessary; the cost of the online path is a small pause on the writer during the final page copy, which is invisible at the request timescale."
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"createdAt": "2026-08-21T00:00:00Z",
|
|
24
|
+
"updatedAt": "2026-08-21T00:00:00Z"
|
|
25
|
+
}
|