@aotter/mantle 0.2.0-alpha.6 → 0.2.0-alpha.7
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/README.md +152 -45
- package/dist/auth/adapter.d.ts +32 -0
- package/dist/auth/adapter.js +285 -0
- package/dist/auth/admin.d.ts +3 -0
- package/dist/auth/admin.js +21 -0
- package/dist/auth/caller.d.ts +86 -0
- package/dist/auth/caller.js +154 -0
- package/dist/auth/hardening.d.ts +24 -0
- package/dist/auth/hardening.js +40 -0
- package/dist/auth/identity.d.ts +121 -0
- package/dist/auth/identity.js +203 -0
- package/dist/auth/oauth.d.ts +31 -0
- package/dist/auth/oauth.js +124 -0
- package/dist/auth/resource-seeds.js +10 -0
- package/dist/auth/routes.d.ts +32 -0
- package/dist/auth/{createAuthRoutes.js → routes.js} +130 -35
- package/dist/build/compiler.d.ts +790 -0
- package/dist/build/compiler.js +6971 -0
- package/dist/{spec → build/spec}/domain/model/ManifestGrammar.d.ts +24 -42
- package/dist/{spec → build/spec}/domain/model/RuntimePlan.d.ts +77 -3
- package/dist/{spec → build/spec}/domain/model/SqlIr.d.ts +35 -6
- package/dist/build/spec/domain/model/UserFields.d.ts +20 -0
- package/dist/{spec → build/spec}/domain/service/PlanFingerprint.d.ts +2 -1
- package/dist/{spec → build/spec}/kernel/diagnostic.d.ts +1 -30
- package/dist/bun/assets.d.ts +2 -0
- package/dist/bun/assets.js +24 -0
- package/dist/domain/adminOrder.js +24 -0
- package/dist/domain/columns.js +55 -0
- package/dist/domain/describe/chunk-ZIQVLA7X.js +363 -0
- package/dist/domain/describe/index.d.ts +58 -0
- package/dist/domain/describe/index.js +115 -0
- package/dist/domain/describe/target-hash.d.ts +8 -0
- package/dist/domain/describe/target-hash.js +12 -0
- package/dist/domain/describe/targets.d.ts +40 -0
- package/dist/domain/entry.js +33 -0
- package/dist/domain/generated-tools.js +17 -0
- package/dist/domain/generation.d.ts +16 -0
- package/dist/domain/generation.js +1 -0
- package/dist/domain/input.js +17 -0
- package/dist/domain/model.js +1 -0
- package/dist/domain/paging.js +204 -0
- package/dist/domain/recipes.js +19 -0
- package/dist/domain/userReferences.js +5 -0
- package/dist/domain/wireScalars.js +47 -0
- package/dist/infrastructure/adminEntries.js +153 -0
- package/dist/infrastructure/adminPaging.js +72 -0
- package/dist/infrastructure/artifacts.js +71 -0
- package/dist/infrastructure/authSchema.js +83 -0
- package/dist/infrastructure/bundle.js +84 -0
- package/dist/infrastructure/cli.js +101 -0
- package/dist/infrastructure/generate.d.ts +14 -0
- package/dist/infrastructure/generate.js +174 -0
- package/dist/infrastructure/generateAuth.d.ts +8 -0
- package/dist/infrastructure/generateAuth.js +17 -0
- package/dist/infrastructure/inputs.js +36 -0
- package/dist/infrastructure/wrangler.js +71 -0
- package/dist/kernel/authorization.d.ts +4 -0
- package/dist/kernel/authorization.js +16 -0
- package/dist/kernel/binds.d.ts +51 -0
- package/dist/kernel/binds.js +45 -0
- package/dist/kernel/caller-identity.d.ts +24 -0
- package/dist/kernel/caller-identity.js +22 -0
- package/dist/kernel/contract-error.d.ts +12 -0
- package/dist/kernel/contract-error.js +14 -0
- package/dist/kernel/contracts.d.ts +139 -0
- package/dist/kernel/contracts.js +92 -0
- package/dist/{spec/domain/service/CloudflareCron.d.ts → kernel/cron.d.ts} +0 -1
- package/dist/{spec/domain/service/CloudflareCron.js → kernel/cron.js} +1 -6
- package/dist/kernel/dialect/common.d.ts +39 -0
- package/dist/kernel/dialect/common.js +6 -0
- package/dist/kernel/dialect/postgres.d.ts +16 -0
- package/dist/kernel/dialect/postgres.js +18 -0
- package/dist/kernel/dialect/sqlite.d.ts +20 -0
- package/dist/kernel/dialect/sqlite.js +34 -0
- package/dist/kernel/driver/bun-sqlite.d.ts +19 -0
- package/dist/kernel/driver/bun-sqlite.js +77 -0
- package/dist/kernel/driver/d1.d.ts +24 -0
- package/dist/kernel/driver/d1.js +22 -0
- package/dist/kernel/driver/postgres.d.ts +25 -0
- package/dist/kernel/driver/postgres.js +95 -0
- package/dist/kernel/driver/transaction-context.d.ts +10 -0
- package/dist/kernel/driver/transaction-context.js +29 -0
- package/dist/kernel/email.d.ts +28 -0
- package/dist/{auth/emailTemplates.js → kernel/email.js} +13 -2
- package/dist/kernel/host-access.d.ts +10 -0
- package/dist/kernel/host-access.js +65 -0
- package/dist/kernel/host-caller.d.ts +38 -0
- package/dist/kernel/host-caller.js +55 -0
- package/dist/kernel/json-body.d.ts +4 -0
- package/dist/kernel/json-body.js +44 -0
- package/dist/kernel/mcp-apps.d.ts +49 -0
- package/dist/kernel/mcp-apps.js +40 -0
- package/dist/kernel/mcp-call.d.ts +5 -0
- package/dist/kernel/mcp-call.js +25 -0
- package/dist/kernel/mcp-handler.js +288 -0
- package/dist/kernel/mcp.d.ts +101 -0
- package/dist/kernel/mcp.js +25 -0
- package/dist/kernel/media.d.ts +27 -0
- package/dist/kernel/media.js +216 -0
- package/dist/kernel/paging.d.ts +55 -0
- package/dist/kernel/paging.js +95 -0
- package/dist/kernel/publishing.d.ts +4 -0
- package/dist/kernel/publishing.js +16 -0
- package/dist/{cloudflare/r2Media.d.ts → kernel/r2-media.d.ts} +4 -5
- package/dist/kernel/r2-media.js +78 -0
- package/dist/kernel/rest-dispatch.js +38 -0
- package/dist/kernel/rest-router.js +63 -0
- package/dist/kernel/rest.d.ts +58 -0
- package/dist/kernel/rest.js +41 -0
- package/dist/kernel/scalars.d.ts +6 -0
- package/dist/kernel/scalars.js +43 -0
- package/dist/kernel/search.js +5 -0
- package/dist/{core/site.d.ts → kernel/site-types.d.ts} +38 -9
- package/dist/kernel/site-types.js +1 -0
- package/dist/kernel/site.d.ts +41 -0
- package/dist/kernel/site.js +32 -0
- package/dist/kernel/store.d.ts +165 -0
- package/dist/kernel/store.js +257 -0
- package/dist/kernel/surface.d.ts +10 -0
- package/dist/kernel/surface.js +19 -0
- package/dist/kernel/sweep.d.ts +17 -0
- package/dist/kernel/sweep.js +27 -0
- package/dist/kernel/translations.d.ts +1 -0
- package/dist/kernel/translations.js +13 -0
- package/dist/kernel/user-caller.d.ts +31 -0
- package/dist/kernel/user-caller.js +67 -0
- package/dist/kernel/user-field-name.js +3 -0
- package/dist/kernel/user-fields.d.ts +34 -0
- package/dist/kernel/user-fields.js +71 -0
- package/dist/kernel/validation.d.ts +15 -0
- package/dist/kernel/validation.js +54 -0
- package/dist/kernel/web-gateway.js +68 -0
- package/dist/kernel/web-head.js +15 -0
- package/dist/kernel/web-response.js +8 -0
- package/dist/kernel/web.d.ts +75 -0
- package/dist/kernel/web.js +155 -0
- package/dist/kernel/where.js +27 -0
- package/dist/testing/index.d.ts +1 -37
- package/dist/testing/index.js +1 -43
- package/dist/usecase/adminBindings.js +142 -0
- package/dist/usecase/adminDescriptors.js +153 -0
- package/dist/usecase/generate.js +164 -0
- package/dist/usecase/handlers.js +21 -0
- package/dist/usecase/mcp-media.js +17 -0
- package/dist/usecase/mcp.js +96 -0
- package/dist/usecase/paging.js +72 -0
- package/dist/usecase/publishing.js +63 -0
- package/dist/usecase/refusals.js +27 -0
- package/dist/usecase/rest.js +54 -0
- package/dist/usecase/search.js +7 -0
- package/dist/usecase/site.js +40 -0
- package/dist/usecase/stores.js +62 -0
- package/dist/usecase/translations.js +78 -0
- package/dist/usecase/ttl.js +20 -0
- package/dist/usecase/validation.js +132 -0
- package/dist/usecase/web.js +22 -0
- package/docs/examples/README.md +31 -16
- package/docs/examples/app-shell/README.md +48 -0
- package/docs/examples/app-shell/package.json +34 -0
- package/docs/examples/app-shell/pnpm-workspace.yaml +8 -0
- package/docs/examples/app-shell/smoke-kit.mjs +100 -0
- package/docs/examples/app-shell/src/admin.ts +10 -0
- package/docs/examples/app-shell/src/auth.ts +55 -0
- package/docs/examples/app-shell/src/handlers.ts +5 -0
- package/docs/examples/app-shell/src/index.ts +4 -0
- package/docs/examples/app-shell/src/routes.ts +13 -0
- package/docs/examples/app-shell/src/schedule.ts +8 -0
- package/docs/examples/app-shell/src/service.ts +70 -0
- package/docs/examples/app-shell/src/sign-in.ts +41 -0
- package/docs/examples/app-shell/src/signup.ts +8 -0
- package/docs/examples/{reference-service → app-shell}/tsconfig.json +2 -1
- package/docs/examples/app-shell/worker-configuration.d.ts +22 -0
- package/docs/examples/app-shell/wrangler.jsonc +61 -0
- package/docs/examples/club-events/README.md +60 -0
- package/docs/examples/club-events/manifests/club-events.yaml +225 -0
- package/docs/examples/club-events/smoke.mjs +121 -0
- package/docs/examples/club-events/src/handlers.ts +25 -0
- package/docs/examples/club-events/src/signup.ts +9 -0
- package/docs/examples/generated-web/README.md +74 -0
- package/docs/examples/generated-web/posts.yaml +38 -0
- package/docs/examples/generated-web/seed.sql +6 -0
- package/docs/examples/generated-web/src/worker.ts +43 -0
- package/docs/examples/generated-web/tsconfig.json +8 -0
- package/docs/examples/generated-web/wrangler.jsonc +7 -0
- package/docs/examples/purchasing/.dev.vars.example +6 -0
- package/docs/examples/purchasing/README.md +90 -0
- package/docs/examples/purchasing/manifests/purchasing.yaml +341 -0
- package/docs/examples/purchasing/seed.sql +4 -0
- package/docs/examples/purchasing/smoke.mjs +171 -0
- package/docs/examples/purchasing/src/admin.ts +12 -0
- package/docs/examples/purchasing/src/handlers.ts +33 -0
- package/docs/examples/purchasing/src/notify.ts +29 -0
- package/docs/examples/purchasing/src/requests-page.ts +57 -0
- package/docs/examples/purchasing/src/routes.ts +53 -0
- package/docs/examples/purchasing/src/schedule.ts +31 -0
- package/docs/examples/purchasing/src/signup.ts +5 -0
- package/docs/examples/purchasing/src/supplier.ts +32 -0
- package/docs/examples/purchasing/wrangler.jsonc +68 -0
- package/docs/examples/recipes/README.md +58 -0
- package/docs/examples/recipes/manifests/recipes.yaml +75 -0
- package/docs/examples/recipes/smoke.mjs +102 -0
- package/docs/examples/recipes/src/media.ts +13 -0
- package/docs/examples/recipes/src/pages.ts +99 -0
- package/docs/examples/recipes/src/routes.ts +71 -0
- package/docs/examples/recipes/src/site-config.ts +12 -0
- package/docs/examples/recipes/wrangler.jsonc +73 -0
- package/docs/handbook/cloudflare/authentication.md +142 -212
- package/docs/handbook/cloudflare/chatgpt-sites.md +4 -113
- package/docs/handbook/cloudflare/deploy-and-operate.md +20 -106
- package/docs/handbook/cloudflare/media-r2.md +62 -133
- package/docs/handbook/cloudflare/service-entry.md +180 -116
- package/docs/handbook/concepts/authorization.md +10 -123
- package/docs/handbook/concepts/four-atoms.md +9 -92
- package/docs/handbook/concepts/lifecycle-and-locales.md +9 -80
- package/docs/handbook/concepts/mcp-and-agents.md +10 -141
- package/docs/handbook/concepts/procedures-and-triggers.md +5 -162
- package/docs/handbook/concepts/runtime-and-adapters.md +15 -224
- package/docs/handbook/concepts/views.md +10 -109
- package/docs/handbook/examples/hub.md +2 -18
- package/docs/handbook/guides/adapter-guide.md +11 -0
- package/docs/handbook/guides/admin-extensions.md +12 -183
- package/docs/handbook/guides/admin-ui.md +5 -164
- package/docs/handbook/guides/agent-setup.md +5 -18
- package/docs/handbook/guides/email.md +86 -0
- package/docs/handbook/guides/mcp-apps.md +44 -0
- package/docs/handbook/guides/native-admin.md +298 -0
- package/docs/handbook/guides/native-execution.md +132 -0
- package/docs/handbook/guides/oauth.md +105 -0
- package/docs/handbook/guides/postgres-adapters.md +56 -0
- package/docs/handbook/guides/public-pages.md +53 -0
- package/docs/handbook/guides/size-and-startup.md +9 -0
- package/docs/handbook/guides/typed-queries.md +39 -102
- package/docs/handbook/navigation.json +164 -31
- package/docs/handbook/reference/admin-descriptors.md +88 -0
- package/docs/handbook/reference/authorization.md +44 -52
- package/docs/handbook/reference/describe.md +56 -0
- package/docs/handbook/reference/diagnostics.md +15 -79
- package/docs/handbook/reference/features.md +45 -53
- package/docs/handbook/reference/manifest.md +6 -69
- package/docs/handbook/reference/procedure.md +9 -118
- package/docs/handbook/reference/schema.md +75 -185
- package/docs/handbook/reference/site-config.md +5 -65
- package/docs/handbook/reference/surface.md +279 -97
- package/docs/handbook/reference/trigger.md +24 -93
- package/docs/handbook/reference/view.md +32 -160
- package/docs/handbook/releases/index.md +48 -13
- package/docs/handbook/start/overview.md +9 -56
- package/docs/handbook/start/project-and-cli.md +40 -149
- package/docs/handbook/start/quickstart-worker.md +38 -116
- package/docs/skills/develop/SKILL.md +34 -123
- package/docs/skills/develop/mcp-app.md +37 -77
- package/docs/skills/integrate/SKILL.md +42 -84
- package/docs/skills/media-gc/SKILL.md +14 -3
- package/docs/skills/provision/SKILL.md +25 -91
- package/docs/skills/update/SKILL.md +19 -43
- package/docs/source/scripts/postgres-adapter.ts +101 -0
- package/docs/upgrade-0.1-to-0.2.md +25 -9
- package/package.json +96 -112
- package/skills/.keep +0 -0
- package/skills/README.md +72 -0
- package/skills/mantle/SKILL.md +135 -0
- package/skills/mantle/references/local-testing.md +11 -0
- package/skills/mantle/references/web.md +41 -0
- package/skills/mantle/references/website.md +47 -0
- package/dist/admin/consent.d.ts +0 -17
- package/dist/admin/consent.d.ts.map +0 -1
- package/dist/admin/consent.js +0 -17
- package/dist/admin/consent.js.map +0 -1
- package/dist/admin/createAdminSurface.d.ts +0 -25
- package/dist/admin/createAdminSurface.d.ts.map +0 -1
- package/dist/admin/createAdminSurface.js +0 -635
- package/dist/admin/createAdminSurface.js.map +0 -1
- package/dist/admin/design.d.ts +0 -7
- package/dist/admin/design.d.ts.map +0 -1
- package/dist/admin/design.js +0 -18
- package/dist/admin/design.js.map +0 -1
- package/dist/admin/developerConsole.d.ts +0 -267
- package/dist/admin/developerConsole.d.ts.map +0 -1
- package/dist/admin/developerConsole.js +0 -136
- package/dist/admin/developerConsole.js.map +0 -1
- package/dist/admin/extensions.d.ts +0 -290
- package/dist/admin/extensions.d.ts.map +0 -1
- package/dist/admin/extensions.js +0 -532
- package/dist/admin/extensions.js.map +0 -1
- package/dist/admin/identity.d.ts +0 -62
- package/dist/admin/identity.d.ts.map +0 -1
- package/dist/admin/identity.js +0 -7
- package/dist/admin/identity.js.map +0 -1
- package/dist/admin/index.d.ts +0 -7
- package/dist/admin/index.d.ts.map +0 -1
- package/dist/admin/index.js +0 -7
- package/dist/admin/index.js.map +0 -1
- package/dist/admin/procedureFlow.d.ts +0 -38
- package/dist/admin/procedureFlow.d.ts.map +0 -1
- package/dist/admin/procedureFlow.js +0 -188
- package/dist/admin/procedureFlow.js.map +0 -1
- package/dist/auth/ConsoleEmailSender.d.ts +0 -15
- package/dist/auth/ConsoleEmailSender.d.ts.map +0 -1
- package/dist/auth/ConsoleEmailSender.js +0 -19
- package/dist/auth/ConsoleEmailSender.js.map +0 -1
- package/dist/auth/appleClientSecret.d.ts +0 -75
- package/dist/auth/appleClientSecret.d.ts.map +0 -1
- package/dist/auth/appleClientSecret.js +0 -116
- package/dist/auth/appleClientSecret.js.map +0 -1
- package/dist/auth/buildAuth.d.ts +0 -4568
- package/dist/auth/buildAuth.d.ts.map +0 -1
- package/dist/auth/buildAuth.js +0 -312
- package/dist/auth/buildAuth.js.map +0 -1
- package/dist/auth/callerResolver.d.ts +0 -52
- package/dist/auth/callerResolver.d.ts.map +0 -1
- package/dist/auth/callerResolver.js +0 -52
- package/dist/auth/callerResolver.js.map +0 -1
- package/dist/auth/createAuthRoutes.d.ts +0 -22
- package/dist/auth/createAuthRoutes.d.ts.map +0 -1
- package/dist/auth/createAuthRoutes.js.map +0 -1
- package/dist/auth/createMantleAuth.d.ts +0 -3
- package/dist/auth/createMantleAuth.d.ts.map +0 -1
- package/dist/auth/createMantleAuth.js +0 -504
- package/dist/auth/createMantleAuth.js.map +0 -1
- package/dist/auth/db.d.ts +0 -18
- package/dist/auth/db.d.ts.map +0 -1
- package/dist/auth/db.js +0 -27
- package/dist/auth/db.js.map +0 -1
- package/dist/auth/emailTemplates.d.ts +0 -7
- package/dist/auth/emailTemplates.d.ts.map +0 -1
- package/dist/auth/emailTemplates.js.map +0 -1
- package/dist/auth/index.d.ts +0 -9
- package/dist/auth/index.d.ts.map +0 -1
- package/dist/auth/index.js +0 -7
- package/dist/auth/index.js.map +0 -1
- package/dist/auth/methods.d.ts +0 -717
- package/dist/auth/methods.d.ts.map +0 -1
- package/dist/auth/methods.js +0 -321
- package/dist/auth/methods.js.map +0 -1
- package/dist/auth/oauthTokens.d.ts +0 -24
- package/dist/auth/oauthTokens.d.ts.map +0 -1
- package/dist/auth/oauthTokens.js +0 -146
- package/dist/auth/oauthTokens.js.map +0 -1
- package/dist/auth/setupIncomplete.d.ts +0 -16
- package/dist/auth/setupIncomplete.d.ts.map +0 -1
- package/dist/auth/setupIncomplete.js +0 -50
- package/dist/auth/setupIncomplete.js.map +0 -1
- package/dist/auth/types.d.ts +0 -440
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js +0 -10
- package/dist/auth/types.js.map +0 -1
- package/dist/bun/index.d.ts +0 -21
- package/dist/bun/index.d.ts.map +0 -1
- package/dist/bun/index.js +0 -46
- package/dist/bun/index.js.map +0 -1
- package/dist/cli/emitModule.d.ts +0 -7
- package/dist/cli/emitModule.d.ts.map +0 -1
- package/dist/cli/emitModule.js +0 -127
- package/dist/cli/emitModule.js.map +0 -1
- package/dist/cli/generate.d.ts +0 -8
- package/dist/cli/generate.d.ts.map +0 -1
- package/dist/cli/generate.js +0 -391
- package/dist/cli/generate.js.map +0 -1
- package/dist/cli/main.d.ts +0 -3
- package/dist/cli/main.d.ts.map +0 -1
- package/dist/cli/main.js +0 -21
- package/dist/cli/main.js.map +0 -1
- package/dist/cli/preset.d.ts +0 -18
- package/dist/cli/preset.d.ts.map +0 -1
- package/dist/cli/preset.js +0 -405
- package/dist/cli/preset.js.map +0 -1
- package/dist/cloudflare/index.d.ts +0 -25
- package/dist/cloudflare/index.d.ts.map +0 -1
- package/dist/cloudflare/index.js +0 -16
- package/dist/cloudflare/index.js.map +0 -1
- package/dist/cloudflare/r2Media.d.ts.map +0 -1
- package/dist/cloudflare/r2Media.js +0 -69
- package/dist/cloudflare/r2Media.js.map +0 -1
- package/dist/core/caller.d.ts +0 -35
- package/dist/core/caller.d.ts.map +0 -1
- package/dist/core/caller.js +0 -3
- package/dist/core/caller.js.map +0 -1
- package/dist/core/createMantle.d.ts +0 -22
- package/dist/core/createMantle.d.ts.map +0 -1
- package/dist/core/createMantle.js +0 -117
- package/dist/core/createMantle.js.map +0 -1
- package/dist/core/dialect.d.ts +0 -53
- package/dist/core/dialect.d.ts.map +0 -1
- package/dist/core/dialect.js +0 -7
- package/dist/core/dialect.js.map +0 -1
- package/dist/core/driver.d.ts +0 -24
- package/dist/core/driver.d.ts.map +0 -1
- package/dist/core/driver.js +0 -2
- package/dist/core/driver.js.map +0 -1
- package/dist/core/email.d.ts +0 -17
- package/dist/core/email.d.ts.map +0 -1
- package/dist/core/email.js +0 -2
- package/dist/core/email.js.map +0 -1
- package/dist/core/index.d.ts +0 -16
- package/dist/core/index.d.ts.map +0 -1
- package/dist/core/index.js +0 -16
- package/dist/core/index.js.map +0 -1
- package/dist/core/invocation.d.ts +0 -66
- package/dist/core/invocation.d.ts.map +0 -1
- package/dist/core/invocation.js +0 -3
- package/dist/core/invocation.js.map +0 -1
- package/dist/core/observation.d.ts +0 -3
- package/dist/core/observation.d.ts.map +0 -1
- package/dist/core/observation.js +0 -10
- package/dist/core/observation.js.map +0 -1
- package/dist/core/runtime/auth.d.ts +0 -9
- package/dist/core/runtime/auth.d.ts.map +0 -1
- package/dist/core/runtime/auth.js +0 -39
- package/dist/core/runtime/auth.js.map +0 -1
- package/dist/core/runtime/createRuntime.d.ts +0 -23
- package/dist/core/runtime/createRuntime.d.ts.map +0 -1
- package/dist/core/runtime/createRuntime.js +0 -214
- package/dist/core/runtime/createRuntime.js.map +0 -1
- package/dist/core/runtime/verifyPlan.d.ts +0 -34
- package/dist/core/runtime/verifyPlan.d.ts.map +0 -1
- package/dist/core/runtime/verifyPlan.js +0 -301
- package/dist/core/runtime/verifyPlan.js.map +0 -1
- package/dist/core/service.d.ts +0 -45
- package/dist/core/service.d.ts.map +0 -1
- package/dist/core/service.js +0 -2
- package/dist/core/service.js.map +0 -1
- package/dist/core/sessionUser.d.ts +0 -14
- package/dist/core/sessionUser.d.ts.map +0 -1
- package/dist/core/sessionUser.js +0 -4
- package/dist/core/sessionUser.js.map +0 -1
- package/dist/core/site.d.ts.map +0 -1
- package/dist/core/site.js +0 -2
- package/dist/core/site.js.map +0 -1
- package/dist/core/siteConfig.d.ts +0 -5
- package/dist/core/siteConfig.d.ts.map +0 -1
- package/dist/core/siteConfig.js +0 -24
- package/dist/core/siteConfig.js.map +0 -1
- package/dist/core/sql/allowlist.d.ts +0 -67
- package/dist/core/sql/allowlist.d.ts.map +0 -1
- package/dist/core/sql/allowlist.js +0 -737
- package/dist/core/sql/allowlist.js.map +0 -1
- package/dist/core/sql/ast.d.ts +0 -24
- package/dist/core/sql/ast.d.ts.map +0 -1
- package/dist/core/sql/ast.js +0 -32
- package/dist/core/sql/ast.js.map +0 -1
- package/dist/core/sql/compile.d.ts +0 -50
- package/dist/core/sql/compile.d.ts.map +0 -1
- package/dist/core/sql/compile.js +0 -48
- package/dist/core/sql/compile.js.map +0 -1
- package/dist/core/sql/policy.d.ts +0 -123
- package/dist/core/sql/policy.d.ts.map +0 -1
- package/dist/core/sql/policy.js +0 -398
- package/dist/core/sql/policy.js.map +0 -1
- package/dist/core/sql/positions.d.ts +0 -30
- package/dist/core/sql/positions.d.ts.map +0 -1
- package/dist/core/sql/positions.js +0 -22
- package/dist/core/sql/positions.js.map +0 -1
- package/dist/core/sql/run.d.ts +0 -68
- package/dist/core/sql/run.d.ts.map +0 -1
- package/dist/core/sql/run.js +0 -384
- package/dist/core/sql/run.js.map +0 -1
- package/dist/core/store/createStore.d.ts +0 -49
- package/dist/core/store/createStore.d.ts.map +0 -1
- package/dist/core/store/createStore.js +0 -227
- package/dist/core/store/createStore.js.map +0 -1
- package/dist/core/store/cursor.d.ts +0 -4
- package/dist/core/store/cursor.d.ts.map +0 -1
- package/dist/core/store/cursor.js +0 -22
- package/dist/core/store/cursor.js.map +0 -1
- package/dist/core/store/json.d.ts +0 -80
- package/dist/core/store/json.d.ts.map +0 -1
- package/dist/core/store/json.js +0 -342
- package/dist/core/store/json.js.map +0 -1
- package/dist/core/store.d.ts +0 -160
- package/dist/core/store.d.ts.map +0 -1
- package/dist/core/store.js +0 -2
- package/dist/core/store.js.map +0 -1
- package/dist/core/wire.d.ts +0 -20
- package/dist/core/wire.d.ts.map +0 -1
- package/dist/core/wire.js +0 -84
- package/dist/core/wire.js.map +0 -1
- package/dist/core/withCaller.d.ts +0 -24
- package/dist/core/withCaller.d.ts.map +0 -1
- package/dist/core/withCaller.js +0 -35
- package/dist/core/withCaller.js.map +0 -1
- package/dist/d1/adapter.d.ts +0 -12
- package/dist/d1/adapter.d.ts.map +0 -1
- package/dist/d1/adapter.js +0 -23
- package/dist/d1/adapter.js.map +0 -1
- package/dist/d1/codec.d.ts +0 -14
- package/dist/d1/codec.d.ts.map +0 -1
- package/dist/d1/codec.js +0 -136
- package/dist/d1/codec.js.map +0 -1
- package/dist/d1/compile/index.d.ts +0 -9
- package/dist/d1/compile/index.d.ts.map +0 -1
- package/dist/d1/compile/index.js +0 -9
- package/dist/d1/compile/index.js.map +0 -1
- package/dist/d1/dialect.d.ts +0 -4
- package/dist/d1/dialect.d.ts.map +0 -1
- package/dist/d1/dialect.js +0 -13
- package/dist/d1/dialect.js.map +0 -1
- package/dist/d1/executor.d.ts +0 -15
- package/dist/d1/executor.d.ts.map +0 -1
- package/dist/d1/executor.js +0 -96
- package/dist/d1/executor.js.map +0 -1
- package/dist/d1/index.d.ts +0 -6
- package/dist/d1/index.d.ts.map +0 -1
- package/dist/d1/index.js +0 -6
- package/dist/d1/index.js.map +0 -1
- package/dist/d1/lower.d.ts +0 -8
- package/dist/d1/lower.d.ts.map +0 -1
- package/dist/d1/lower.js +0 -167
- package/dist/d1/lower.js.map +0 -1
- package/dist/d1/media.d.ts +0 -5
- package/dist/d1/media.d.ts.map +0 -1
- package/dist/d1/media.js +0 -157
- package/dist/d1/media.js.map +0 -1
- package/dist/d1/migrations.d.ts +0 -12
- package/dist/d1/migrations.d.ts.map +0 -1
- package/dist/d1/migrations.js +0 -111
- package/dist/d1/migrations.js.map +0 -1
- package/dist/d1/print.d.ts +0 -28
- package/dist/d1/print.d.ts.map +0 -1
- package/dist/d1/print.js +0 -54
- package/dist/d1/print.js.map +0 -1
- package/dist/d1/site.d.ts +0 -17
- package/dist/d1/site.d.ts.map +0 -1
- package/dist/d1/site.js +0 -63
- package/dist/d1/site.js.map +0 -1
- package/dist/d1/storage.d.ts +0 -34
- package/dist/d1/storage.d.ts.map +0 -1
- package/dist/d1/storage.js +0 -288
- package/dist/d1/storage.js.map +0 -1
- package/dist/d1/tz.d.ts +0 -21
- package/dist/d1/tz.d.ts.map +0 -1
- package/dist/d1/tz.js +0 -54
- package/dist/d1/tz.js.map +0 -1
- package/dist/d1/validator.d.ts +0 -10
- package/dist/d1/validator.d.ts.map +0 -1
- package/dist/d1/validator.js +0 -33
- package/dist/d1/validator.js.map +0 -1
- package/dist/mcp/apps.d.ts +0 -43
- package/dist/mcp/apps.d.ts.map +0 -1
- package/dist/mcp/apps.js +0 -57
- package/dist/mcp/apps.js.map +0 -1
- package/dist/mcp/catalog.d.ts +0 -55
- package/dist/mcp/catalog.d.ts.map +0 -1
- package/dist/mcp/catalog.js +0 -81
- package/dist/mcp/catalog.js.map +0 -1
- package/dist/mcp/createMcpSurface.d.ts +0 -60
- package/dist/mcp/createMcpSurface.d.ts.map +0 -1
- package/dist/mcp/createMcpSurface.js +0 -182
- package/dist/mcp/createMcpSurface.js.map +0 -1
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/index.d.ts.map +0 -1
- package/dist/mcp/index.js +0 -4
- package/dist/mcp/index.js.map +0 -1
- package/dist/mcp/media.d.ts +0 -9
- package/dist/mcp/media.d.ts.map +0 -1
- package/dist/mcp/media.js +0 -33
- package/dist/mcp/media.js.map +0 -1
- package/dist/postgres/adapter.d.ts +0 -23
- package/dist/postgres/adapter.d.ts.map +0 -1
- package/dist/postgres/adapter.js +0 -50
- package/dist/postgres/adapter.js.map +0 -1
- package/dist/postgres/codec.d.ts +0 -13
- package/dist/postgres/codec.d.ts.map +0 -1
- package/dist/postgres/codec.js +0 -110
- package/dist/postgres/codec.js.map +0 -1
- package/dist/postgres/compile/index.d.ts +0 -9
- package/dist/postgres/compile/index.d.ts.map +0 -1
- package/dist/postgres/compile/index.js +0 -9
- package/dist/postgres/compile/index.js.map +0 -1
- package/dist/postgres/driver.d.ts +0 -109
- package/dist/postgres/driver.d.ts.map +0 -1
- package/dist/postgres/driver.js +0 -186
- package/dist/postgres/driver.js.map +0 -1
- package/dist/postgres/executor.d.ts +0 -28
- package/dist/postgres/executor.d.ts.map +0 -1
- package/dist/postgres/executor.js +0 -96
- package/dist/postgres/executor.js.map +0 -1
- package/dist/postgres/index.d.ts +0 -8
- package/dist/postgres/index.d.ts.map +0 -1
- package/dist/postgres/index.js +0 -8
- package/dist/postgres/index.js.map +0 -1
- package/dist/postgres/lower.d.ts +0 -6
- package/dist/postgres/lower.d.ts.map +0 -1
- package/dist/postgres/lower.js +0 -152
- package/dist/postgres/lower.js.map +0 -1
- package/dist/postgres/print.d.ts +0 -11
- package/dist/postgres/print.d.ts.map +0 -1
- package/dist/postgres/print.js +0 -108
- package/dist/postgres/print.js.map +0 -1
- package/dist/postgres/session.d.ts +0 -9
- package/dist/postgres/session.d.ts.map +0 -1
- package/dist/postgres/session.js +0 -111
- package/dist/postgres/session.js.map +0 -1
- package/dist/postgres/storage.d.ts +0 -32
- package/dist/postgres/storage.d.ts.map +0 -1
- package/dist/postgres/storage.js +0 -283
- package/dist/postgres/storage.js.map +0 -1
- package/dist/postgres/validator.d.ts +0 -13
- package/dist/postgres/validator.d.ts.map +0 -1
- package/dist/postgres/validator.js +0 -53
- package/dist/postgres/validator.js.map +0 -1
- package/dist/spec/domain/index.d.ts +0 -3
- package/dist/spec/domain/index.d.ts.map +0 -1
- package/dist/spec/domain/index.js +0 -3
- package/dist/spec/domain/index.js.map +0 -1
- package/dist/spec/domain/model/ContentState.d.ts +0 -8
- package/dist/spec/domain/model/ContentState.d.ts.map +0 -1
- package/dist/spec/domain/model/ContentState.js +0 -7
- package/dist/spec/domain/model/ContentState.js.map +0 -1
- package/dist/spec/domain/model/Entry.d.ts +0 -29
- package/dist/spec/domain/model/Entry.d.ts.map +0 -1
- package/dist/spec/domain/model/Entry.js +0 -16
- package/dist/spec/domain/model/Entry.js.map +0 -1
- package/dist/spec/domain/model/Locale.d.ts +0 -30
- package/dist/spec/domain/model/Locale.d.ts.map +0 -1
- package/dist/spec/domain/model/Locale.js +0 -33
- package/dist/spec/domain/model/Locale.js.map +0 -1
- package/dist/spec/domain/model/ManifestGrammar.d.ts.map +0 -1
- package/dist/spec/domain/model/ManifestGrammar.js +0 -153
- package/dist/spec/domain/model/ManifestGrammar.js.map +0 -1
- package/dist/spec/domain/model/MediaMimeAccept.d.ts +0 -55
- package/dist/spec/domain/model/MediaMimeAccept.d.ts.map +0 -1
- package/dist/spec/domain/model/MediaMimeAccept.js +0 -90
- package/dist/spec/domain/model/MediaMimeAccept.js.map +0 -1
- package/dist/spec/domain/model/RuntimePlan.d.ts.map +0 -1
- package/dist/spec/domain/model/RuntimePlan.js +0 -4
- package/dist/spec/domain/model/RuntimePlan.js.map +0 -1
- package/dist/spec/domain/model/SiteConfig.d.ts +0 -173
- package/dist/spec/domain/model/SiteConfig.d.ts.map +0 -1
- package/dist/spec/domain/model/SiteConfig.js +0 -13
- package/dist/spec/domain/model/SiteConfig.js.map +0 -1
- package/dist/spec/domain/model/SqlIr.d.ts.map +0 -1
- package/dist/spec/domain/model/SqlIr.js +0 -95
- package/dist/spec/domain/model/SqlIr.js.map +0 -1
- package/dist/spec/domain/model/index.d.ts +0 -14
- package/dist/spec/domain/model/index.d.ts.map +0 -1
- package/dist/spec/domain/model/index.js +0 -14
- package/dist/spec/domain/model/index.js.map +0 -1
- package/dist/spec/domain/service/CloudflareCron.d.ts.map +0 -1
- package/dist/spec/domain/service/CloudflareCron.js.map +0 -1
- package/dist/spec/domain/service/CrossSchemaChecker.d.ts +0 -34
- package/dist/spec/domain/service/CrossSchemaChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/CrossSchemaChecker.js +0 -114
- package/dist/spec/domain/service/CrossSchemaChecker.js.map +0 -1
- package/dist/spec/domain/service/EntryDataValidator.d.ts +0 -56
- package/dist/spec/domain/service/EntryDataValidator.d.ts.map +0 -1
- package/dist/spec/domain/service/EntryDataValidator.js +0 -88
- package/dist/spec/domain/service/EntryDataValidator.js.map +0 -1
- package/dist/spec/domain/service/JsonSchemaToZod.d.ts +0 -29
- package/dist/spec/domain/service/JsonSchemaToZod.d.ts.map +0 -1
- package/dist/spec/domain/service/JsonSchemaToZod.js +0 -156
- package/dist/spec/domain/service/JsonSchemaToZod.js.map +0 -1
- package/dist/spec/domain/service/LifecycleStateMachine.d.ts +0 -75
- package/dist/spec/domain/service/LifecycleStateMachine.d.ts.map +0 -1
- package/dist/spec/domain/service/LifecycleStateMachine.js +0 -76
- package/dist/spec/domain/service/LifecycleStateMachine.js.map +0 -1
- package/dist/spec/domain/service/LocaleCanonicalizer.d.ts +0 -29
- package/dist/spec/domain/service/LocaleCanonicalizer.d.ts.map +0 -1
- package/dist/spec/domain/service/LocaleCanonicalizer.js +0 -96
- package/dist/spec/domain/service/LocaleCanonicalizer.js.map +0 -1
- package/dist/spec/domain/service/ManifestFieldChecks.d.ts +0 -60
- package/dist/spec/domain/service/ManifestFieldChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestFieldChecks.js +0 -116
- package/dist/spec/domain/service/ManifestFieldChecks.js.map +0 -1
- package/dist/spec/domain/service/ManifestGraphValidator.d.ts +0 -15
- package/dist/spec/domain/service/ManifestGraphValidator.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestGraphValidator.js +0 -225
- package/dist/spec/domain/service/ManifestGraphValidator.js.map +0 -1
- package/dist/spec/domain/service/ManifestLinker.d.ts +0 -45
- package/dist/spec/domain/service/ManifestLinker.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestLinker.js +0 -92
- package/dist/spec/domain/service/ManifestLinker.js.map +0 -1
- package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts +0 -16
- package/dist/spec/domain/service/ManifestLocaleTrimmer.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestLocaleTrimmer.js +0 -76
- package/dist/spec/domain/service/ManifestLocaleTrimmer.js.map +0 -1
- package/dist/spec/domain/service/ManifestParser.d.ts +0 -49
- package/dist/spec/domain/service/ManifestParser.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestParser.js +0 -203
- package/dist/spec/domain/service/ManifestParser.js.map +0 -1
- package/dist/spec/domain/service/ManifestPartition.d.ts +0 -9
- package/dist/spec/domain/service/ManifestPartition.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestPartition.js +0 -19
- package/dist/spec/domain/service/ManifestPartition.js.map +0 -1
- package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts +0 -33
- package/dist/spec/domain/service/ManifestPathDiagnoser.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestPathDiagnoser.js +0 -43
- package/dist/spec/domain/service/ManifestPathDiagnoser.js.map +0 -1
- package/dist/spec/domain/service/ManifestSourceSpans.d.ts +0 -10
- package/dist/spec/domain/service/ManifestSourceSpans.d.ts.map +0 -1
- package/dist/spec/domain/service/ManifestSourceSpans.js +0 -76
- package/dist/spec/domain/service/ManifestSourceSpans.js.map +0 -1
- package/dist/spec/domain/service/McpToolNaming.d.ts +0 -25
- package/dist/spec/domain/service/McpToolNaming.d.ts.map +0 -1
- package/dist/spec/domain/service/McpToolNaming.js +0 -50
- package/dist/spec/domain/service/McpToolNaming.js.map +0 -1
- package/dist/spec/domain/service/PlanFingerprint.d.ts.map +0 -1
- package/dist/spec/domain/service/PlanFingerprint.js +0 -14
- package/dist/spec/domain/service/PlanFingerprint.js.map +0 -1
- package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts +0 -4
- package/dist/spec/domain/service/ProcedureViewSpecChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/ProcedureViewSpecChecks.js +0 -211
- package/dist/spec/domain/service/ProcedureViewSpecChecks.js.map +0 -1
- package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts +0 -44
- package/dist/spec/domain/service/SchemaAdminUiChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaAdminUiChecker.js +0 -333
- package/dist/spec/domain/service/SchemaAdminUiChecker.js.map +0 -1
- package/dist/spec/domain/service/SchemaIndexChecker.d.ts +0 -33
- package/dist/spec/domain/service/SchemaIndexChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaIndexChecker.js +0 -256
- package/dist/spec/domain/service/SchemaIndexChecker.js.map +0 -1
- package/dist/spec/domain/service/SchemaSearchChecker.d.ts +0 -11
- package/dist/spec/domain/service/SchemaSearchChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaSearchChecker.js +0 -78
- package/dist/spec/domain/service/SchemaSearchChecker.js.map +0 -1
- package/dist/spec/domain/service/SchemaSpecChecks.d.ts +0 -31
- package/dist/spec/domain/service/SchemaSpecChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/SchemaSpecChecks.js +0 -445
- package/dist/spec/domain/service/SchemaSpecChecks.js.map +0 -1
- package/dist/spec/domain/service/SiteDefaultsValidator.d.ts +0 -39
- package/dist/spec/domain/service/SiteDefaultsValidator.d.ts.map +0 -1
- package/dist/spec/domain/service/SiteDefaultsValidator.js +0 -194
- package/dist/spec/domain/service/SiteDefaultsValidator.js.map +0 -1
- package/dist/spec/domain/service/SqlClassify.d.ts +0 -19
- package/dist/spec/domain/service/SqlClassify.d.ts.map +0 -1
- package/dist/spec/domain/service/SqlClassify.js +0 -42
- package/dist/spec/domain/service/SqlClassify.js.map +0 -1
- package/dist/spec/domain/service/SqlRefusal.d.ts +0 -16
- package/dist/spec/domain/service/SqlRefusal.d.ts.map +0 -1
- package/dist/spec/domain/service/SqlRefusal.js +0 -20
- package/dist/spec/domain/service/SqlRefusal.js.map +0 -1
- package/dist/spec/domain/service/SqlTypes.d.ts +0 -40
- package/dist/spec/domain/service/SqlTypes.d.ts.map +0 -1
- package/dist/spec/domain/service/SqlTypes.js +0 -110
- package/dist/spec/domain/service/SqlTypes.js.map +0 -1
- package/dist/spec/domain/service/StaffRoleHierarchy.d.ts +0 -3
- package/dist/spec/domain/service/StaffRoleHierarchy.d.ts.map +0 -1
- package/dist/spec/domain/service/StaffRoleHierarchy.js +0 -19
- package/dist/spec/domain/service/StaffRoleHierarchy.js.map +0 -1
- package/dist/spec/domain/service/TriggerGraphChecks.d.ts +0 -16
- package/dist/spec/domain/service/TriggerGraphChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/TriggerGraphChecks.js +0 -337
- package/dist/spec/domain/service/TriggerGraphChecks.js.map +0 -1
- package/dist/spec/domain/service/TriggerSpecChecks.d.ts +0 -4
- package/dist/spec/domain/service/TriggerSpecChecks.d.ts.map +0 -1
- package/dist/spec/domain/service/TriggerSpecChecks.js +0 -89
- package/dist/spec/domain/service/TriggerSpecChecks.js.map +0 -1
- package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts +0 -11
- package/dist/spec/domain/service/ValidatedAdminUiProjection.d.ts.map +0 -1
- package/dist/spec/domain/service/ValidatedAdminUiProjection.js +0 -26
- package/dist/spec/domain/service/ValidatedAdminUiProjection.js.map +0 -1
- package/dist/spec/domain/service/ViewAdminUiChecker.d.ts +0 -14
- package/dist/spec/domain/service/ViewAdminUiChecker.d.ts.map +0 -1
- package/dist/spec/domain/service/ViewAdminUiChecker.js +0 -58
- package/dist/spec/domain/service/ViewAdminUiChecker.js.map +0 -1
- package/dist/spec/domain/service/index.d.ts +0 -24
- package/dist/spec/domain/service/index.d.ts.map +0 -1
- package/dist/spec/domain/service/index.js +0 -24
- package/dist/spec/domain/service/index.js.map +0 -1
- package/dist/spec/index.d.ts +0 -10
- package/dist/spec/index.d.ts.map +0 -1
- package/dist/spec/index.js +0 -12
- package/dist/spec/index.js.map +0 -1
- package/dist/spec/infrastructure/cli/parseArgsError.d.ts +0 -16
- package/dist/spec/infrastructure/cli/parseArgsError.d.ts.map +0 -1
- package/dist/spec/infrastructure/cli/parseArgsError.js +0 -34
- package/dist/spec/infrastructure/cli/parseArgsError.js.map +0 -1
- package/dist/spec/infrastructure/index.d.ts +0 -2
- package/dist/spec/infrastructure/index.d.ts.map +0 -1
- package/dist/spec/infrastructure/index.js +0 -2
- package/dist/spec/infrastructure/index.js.map +0 -1
- package/dist/spec/infrastructure/sql/PgQueryParser.d.ts +0 -18
- package/dist/spec/infrastructure/sql/PgQueryParser.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/PgQueryParser.js +0 -17
- package/dist/spec/infrastructure/sql/PgQueryParser.js.map +0 -1
- package/dist/spec/infrastructure/sql/compilePlan.d.ts +0 -37
- package/dist/spec/infrastructure/sql/compilePlan.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/compilePlan.js +0 -287
- package/dist/spec/infrastructure/sql/compilePlan.js.map +0 -1
- package/dist/spec/infrastructure/sql/compileSql.d.ts +0 -35
- package/dist/spec/infrastructure/sql/compileSql.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/compileSql.js +0 -92
- package/dist/spec/infrastructure/sql/compileSql.js.map +0 -1
- package/dist/spec/infrastructure/sql/frontEnd.d.ts +0 -8
- package/dist/spec/infrastructure/sql/frontEnd.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/frontEnd.js +0 -100
- package/dist/spec/infrastructure/sql/frontEnd.js.map +0 -1
- package/dist/spec/infrastructure/sql/index.d.ts +0 -4
- package/dist/spec/infrastructure/sql/index.d.ts.map +0 -1
- package/dist/spec/infrastructure/sql/index.js +0 -4
- package/dist/spec/infrastructure/sql/index.js.map +0 -1
- package/dist/spec/kernel/diagnostic.d.ts.map +0 -1
- package/dist/spec/kernel/diagnostic.js +0 -301
- package/dist/spec/kernel/diagnostic.js.map +0 -1
- package/dist/spec/kernel/index.d.ts +0 -8
- package/dist/spec/kernel/index.d.ts.map +0 -1
- package/dist/spec/kernel/index.js +0 -8
- package/dist/spec/kernel/index.js.map +0 -1
- package/dist/spec/usecase/EmitTypes.d.ts +0 -22
- package/dist/spec/usecase/EmitTypes.d.ts.map +0 -1
- package/dist/spec/usecase/EmitTypes.js +0 -182
- package/dist/spec/usecase/EmitTypes.js.map +0 -1
- package/dist/spec/usecase/ValidateManifestsUseCase.d.ts +0 -8
- package/dist/spec/usecase/ValidateManifestsUseCase.d.ts.map +0 -1
- package/dist/spec/usecase/ValidateManifestsUseCase.js +0 -101
- package/dist/spec/usecase/ValidateManifestsUseCase.js.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts +0 -27
- package/dist/spec/usecase/dto/ValidateManifestsRequest.d.ts.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsRequest.js +0 -2
- package/dist/spec/usecase/dto/ValidateManifestsRequest.js.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts +0 -14
- package/dist/spec/usecase/dto/ValidateManifestsResponse.d.ts.map +0 -1
- package/dist/spec/usecase/dto/ValidateManifestsResponse.js +0 -2
- package/dist/spec/usecase/dto/ValidateManifestsResponse.js.map +0 -1
- package/dist/spec/usecase/dto/index.d.ts +0 -3
- package/dist/spec/usecase/dto/index.d.ts.map +0 -1
- package/dist/spec/usecase/dto/index.js +0 -3
- package/dist/spec/usecase/dto/index.js.map +0 -1
- package/dist/spec/usecase/index.d.ts +0 -10
- package/dist/spec/usecase/index.d.ts.map +0 -1
- package/dist/spec/usecase/index.js +0 -10
- package/dist/spec/usecase/index.js.map +0 -1
- package/dist/testing/cases/before-hook.d.ts +0 -4
- package/dist/testing/cases/before-hook.d.ts.map +0 -1
- package/dist/testing/cases/before-hook.js +0 -71
- package/dist/testing/cases/before-hook.js.map +0 -1
- package/dist/testing/cases/corpus.d.ts +0 -14
- package/dist/testing/cases/corpus.d.ts.map +0 -1
- package/dist/testing/cases/corpus.js +0 -93
- package/dist/testing/cases/corpus.js.map +0 -1
- package/dist/testing/cases/policy.d.ts +0 -87
- package/dist/testing/cases/policy.d.ts.map +0 -1
- package/dist/testing/cases/policy.js +0 -143
- package/dist/testing/cases/policy.js.map +0 -1
- package/dist/testing/cases/printer.d.ts +0 -4
- package/dist/testing/cases/printer.d.ts.map +0 -1
- package/dist/testing/cases/printer.js +0 -34
- package/dist/testing/cases/printer.js.map +0 -1
- package/dist/testing/cases/report-view.d.ts +0 -5
- package/dist/testing/cases/report-view.d.ts.map +0 -1
- package/dist/testing/cases/report-view.js +0 -51
- package/dist/testing/cases/report-view.js.map +0 -1
- package/dist/testing/cases/requisition.d.ts +0 -4
- package/dist/testing/cases/requisition.d.ts.map +0 -1
- package/dist/testing/cases/requisition.js +0 -38
- package/dist/testing/cases/requisition.js.map +0 -1
- package/dist/testing/cases/search-places.d.ts +0 -4
- package/dist/testing/cases/search-places.d.ts.map +0 -1
- package/dist/testing/cases/search-places.js +0 -60
- package/dist/testing/cases/search-places.js.map +0 -1
- package/dist/testing/cases/stock.d.ts +0 -4
- package/dist/testing/cases/stock.d.ts.map +0 -1
- package/dist/testing/cases/stock.js +0 -35
- package/dist/testing/cases/stock.js.map +0 -1
- package/dist/testing/cases/store.d.ts +0 -4
- package/dist/testing/cases/store.d.ts.map +0 -1
- package/dist/testing/cases/store.js +0 -100
- package/dist/testing/cases/store.js.map +0 -1
- package/dist/testing/harness.d.ts +0 -94
- package/dist/testing/harness.d.ts.map +0 -1
- package/dist/testing/harness.js +0 -168
- package/dist/testing/harness.js.map +0 -1
- package/dist/testing/index.d.ts.map +0 -1
- package/dist/testing/index.js.map +0 -1
- package/dist/testing/report.d.ts +0 -15
- package/dist/testing/report.d.ts.map +0 -1
- package/dist/testing/report.js +0 -22
- package/dist/testing/report.js.map +0 -1
- package/dist/web/createRestSurface.d.ts +0 -7
- package/dist/web/createRestSurface.d.ts.map +0 -1
- package/dist/web/createRestSurface.js +0 -41
- package/dist/web/createRestSurface.js.map +0 -1
- package/dist/web/index.d.ts +0 -2
- package/dist/web/index.d.ts.map +0 -1
- package/dist/web/index.js +0 -2
- package/dist/web/index.js.map +0 -1
- package/docs/adr/0001-four-atom-manifest-model.md +0 -440
- package/docs/adr/0002-closed-enums-for-bindings.md +0 -253
- package/docs/adr/0007-ai-as-primary-author.md +0 -473
- package/docs/adr/0008-structured-diagnostic-shape.md +0 -338
- package/docs/adr/0009-consumer-supplied-manifests.md +0 -149
- package/docs/adr/0010-locale-and-translates.md +0 -453
- package/docs/adr/0011-adapter-port-spec.md +0 -281
- package/docs/adr/0012-views-as-public-rest.md +0 -161
- package/docs/adr/0013-agent-provisioned-consumer-projects.md +0 -154
- package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +0 -939
- package/docs/adr/0016-site-semantic-layer.md +0 -70
- package/docs/adr/0017-media-multi-variant-agent-side-optimization.md +0 -181
- package/docs/adr/0018-core-starters-repository-boundary.md +0 -179
- package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +0 -244
- package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +0 -199
- package/docs/adr/0021-retire-starter-scaffolding.md +0 -30
- package/docs/adr/0022-caller-observed-version-occ.md +0 -212
- package/docs/adr/0023-port-failure-contract.md +0 -69
- package/docs/adr/0024-manifest-native-schema-tables.md +0 -264
- package/docs/adr/0025-reserved-native-columns-and-published-only-public-views.md +0 -105
- package/docs/adr/0026-progressive-generate.md +0 -36
- package/docs/adr/0027-scheduled-procedure-triggers.md +0 -31
- package/docs/adr/0028-schema-ttl-expiry.md +0 -33
- package/docs/adr/0029-mcp-apps-interaction-contracts.md +0 -324
- package/docs/adr/0030-store.md +0 -40
- package/docs/adr/0031-host-cloud-core-contract.md +0 -102
- package/docs/adr/0032-store-centric-core-and-service-contract.md +0 -384
- package/docs/adr/0033-storage-converges-to-the-plan.md +0 -92
- package/docs/adr/0034-store-is-authored-as-sql.md +0 -192
- package/docs/adr/0035-sql-dialects.md +0 -154
- package/docs/adr/0036-host-and-dialect.md +0 -65
- package/docs/adr/0037-postgresql-is-the-reference-dialect.md +0 -125
- package/docs/adr/0038-bun-native-host.md +0 -63
- package/docs/adr/0039-postgresql-is-native.md +0 -130
- package/docs/adr/README.md +0 -98
- package/docs/adr/adr-lite-1376-admin-extensions.md +0 -330
- package/docs/adr/adr-lite-803-request-diagnostics.md +0 -38
- package/docs/adr/adr-lite-808-route-readiness.md +0 -47
- package/docs/adr/adr-lite-809-bounded-public-content.md +0 -71
- package/docs/adr/adr-lite-812-native-parity.md +0 -150
- package/docs/adr/adr-lite-823-home-statistics.md +0 -64
- package/docs/adr/adr-lite-842-mcp-authoring.md +0 -30
- package/docs/adr/adr-lite-845-frontend-client.md +0 -38
- package/docs/adr/adr-lite-861-admin-webmcp.md +0 -48
- package/docs/adr/adr-lite-909-admin-ui-kit.md +0 -37
- package/docs/examples/commerce-inventory.md +0 -498
- package/docs/examples/commerce.md +0 -254
- package/docs/examples/guarded-api.md +0 -238
- package/docs/examples/intake-hooks.md +0 -237
- package/docs/examples/intake.md +0 -127
- package/docs/examples/legal-documents.md +0 -218
- package/docs/examples/procurement.md +0 -226
- package/docs/examples/publication.md +0 -211
- package/docs/examples/reference-service/.mantle/generated/mantle.ts +0 -174
- package/docs/examples/reference-service/.mantle/generated/plan.json +0 -1936
- package/docs/examples/reference-service/README.md +0 -33
- package/docs/examples/reference-service/manifests/catalog.yaml +0 -103
- package/docs/examples/reference-service/manifests/orders.yaml +0 -120
- package/docs/examples/reference-service/mantle.config.json +0 -1
- package/docs/examples/reference-service/package.json +0 -27
- package/docs/examples/reference-service/smoke.mjs +0 -160
- package/docs/examples/reference-service/src/handlers.ts +0 -36
- package/docs/examples/reference-service/src/index.ts +0 -33
- package/docs/examples/reference-service/src/service.ts +0 -78
- package/docs/examples/reference-service/wrangler.jsonc +0 -26
- package/docs/examples/reservation.md +0 -142
- /package/docs/examples/{reference-service → app-shell}/.dev.vars.example +0 -0
|
@@ -1,939 +0,0 @@
|
|
|
1
|
-
# ADR-0014: Adapter-owned identity and MCP authorization
|
|
2
|
-
|
|
3
|
-
## Status
|
|
4
|
-
|
|
5
|
-
Accepted. Amended 2026-05-14, 2026-05-15, 2026-06-30, 2026-07-15,
|
|
6
|
-
2026-08-03, 2026-08-22, 2026-09-18, 2026-09-21, and 2026-09-22.
|
|
7
|
-
|
|
8
|
-
## Date
|
|
9
|
-
|
|
10
|
-
2026-05-09 (last amended 2026-09-22)
|
|
11
|
-
|
|
12
|
-
> **Current authority:** the original decision below records the rejected
|
|
13
|
-
> Better-Auth-for-MCP design. The 2026-08-22 Better Auth 1.7 amendment is
|
|
14
|
-
> authoritative where it conflicts with the 2026-05-15 carve-out; the
|
|
15
|
-
> 2026-07-15 normalized authorization boundary still applies. Operational
|
|
16
|
-
> guidance is maintained against the current adapter/runtime.
|
|
17
|
-
|
|
18
|
-
## Context
|
|
19
|
-
|
|
20
|
-
The pre-v0.1.0 auth surface is a hand-rolled GitHub-only flow stitched out of two libraries:
|
|
21
|
-
|
|
22
|
-
- `@cloudflare/workers-oauth-provider` (DCR-compliant authorization server for MCP — `/oauth/{authorize,token,register}`, `.well-known/oauth-authorization-server`, KV-backed token storage)
|
|
23
|
-
- A hand-rolled GitHub upstream OAuth client (`oauth/githubOAuth.ts` ~110 LOC)
|
|
24
|
-
- D1 tables: `users`, `social_logins`, `sessions`, `github_tokens`, `staff` overlay
|
|
25
|
-
- `ensureBootstrapOwner` env-var gated (`ADMIN_GITHUB_LOGIN`)
|
|
26
|
-
- `cms_session` cookie carries the staff session
|
|
27
|
-
- Single `/mcp` route gated to staff bearers only
|
|
28
|
-
|
|
29
|
-
Pre-launch we promised the `publication` family then `community` and `fan-club` (#58 taxonomy). Both require:
|
|
30
|
-
|
|
31
|
-
1. **Multi-IDP end-user login** — GitHub, Google, Apple, plus magic link / email OTP for users without OAuth accounts
|
|
32
|
-
2. **End-user MCP access via DCR** — let signed-in end-users grant a Claude / Cursor / Codex agent read access to their own subscriptions, comments, member-only posts
|
|
33
|
-
|
|
34
|
-
Trying to grow the existing hand-rolled stack into that shape — three IDPs, two paths to magic link, account linking with reauth, scope-based MCP gating, role machinery for both staff and end-user, end-user DCR through `workers-oauth-provider` — accumulates fast (~1500 LOC of auth code by v0.2). Cloudflare itself does not ship a transactional-email-for-app-auth product (Cloudflare Access's "One-time PIN" gates Zero Trust resources, not public-site users), so the email-OTP path needs an external sender regardless.
|
|
35
|
-
|
|
36
|
-
The "single `/mcp` with config flags" pattern explodes combinatorially when scope, role, surface, and feature flags interact. Each new feature multiplies the matrix.
|
|
37
|
-
|
|
38
|
-
A 2026 Workers-friendly auth library — [Better Auth](https://better-auth.com) — covers this entire space:
|
|
39
|
-
|
|
40
|
-
- Identity / sessions / accounts (the obvious thing every auth library does)
|
|
41
|
-
- Multi-IDP via `socialProviders` (GitHub / Google / Apple / 30+ more)
|
|
42
|
-
- Magic link (`magicLink` plugin) and email OTP (`emailOTP` plugin) with pluggable email sender
|
|
43
|
-
- Role machinery (`admin` plugin, `user.role` field on user table)
|
|
44
|
-
- **OAuth 2.1 provider with DCR (`oauthProvider` plugin)** — full RFC 7591 dynamic client registration, RFC 7662 introspection, RFC 7009 revocation, scope-based access control, custom token claims, consent UI redirect customization
|
|
45
|
-
- **MCP plugin (`mcp`)** — purpose-built on top of the OAuth 2.1 provider for MCP DCR; auto-mounts `.well-known/oauth-authorization-server` + `.well-known/oauth-protected-resource`, exposes `auth.api.getMcpSession()` for protected-resource validation
|
|
46
|
-
- Account linking with policies (verified-email match + reauth requirement)
|
|
47
|
-
|
|
48
|
-
Better Auth depends on a Kysely / Drizzle / Prisma adapter for the database, not on any Cloudflare-specific service. The auth machinery remains platform-agnostic.
|
|
49
|
-
|
|
50
|
-
## Decision (historical baseline; amended below)
|
|
51
|
-
|
|
52
|
-
### 1. Better Auth replaces both layers
|
|
53
|
-
|
|
54
|
-
Adopt Better Auth as the SDK's full auth surface. It owns:
|
|
55
|
-
|
|
56
|
-
- `user` / `session` / `account` / `verification` D1 tables (replaces our `users` / `social_logins` / `sessions` / `github_tokens`)
|
|
57
|
-
- Cookie session (replaces `cms_session` with `better-auth.session_token`)
|
|
58
|
-
- Upstream OAuth clients for GitHub, Google, Apple via `socialProviders` (replaces `oauth/githubOAuth.ts`)
|
|
59
|
-
- Magic link plugin (replaces the `email_verifications` table we would otherwise hand-roll)
|
|
60
|
-
- Email OTP plugin
|
|
61
|
-
- `admin` plugin for role machinery (replaces the `staff` table — `user.role` carries the role string)
|
|
62
|
-
- **`oauthProvider` (or `mcp`) plugin for DCR-compliant authorization server** (replaces `@cloudflare/workers-oauth-provider`)
|
|
63
|
-
|
|
64
|
-
`@cloudflare/workers-oauth-provider` is removed entirely. The `OAUTH_KV` binding is no longer required. The whole `packages/adapters/cloudflare/src/oauth/` directory disappears (singleton wiring, hand-rolled GitHub OAuth, consent HTML renderer with locale list — Better Auth's consent flow replaces).
|
|
65
|
-
|
|
66
|
-
The auth runtime stops being an adapter port. `OAuthVerifier` port + `WorkersOAuthVerifier` adapter are deleted. Validating bearer tokens at `/mcp` and `/staff/mcp` becomes `auth.api.getMcpSession(req.raw)` — a direct Better Auth API call, no port indirection.
|
|
67
|
-
|
|
68
|
-
This makes the runtime more platform-agnostic, not less: Better Auth runs on Workers (D1 via Kysely), Bun (sqlite), and Node (postgres) without runtime changes.
|
|
69
|
-
|
|
70
|
-
### 2. `staff` table → `user.role` via Better Auth admin plugin
|
|
71
|
-
|
|
72
|
-
The `admin` plugin stores a `role` field on the `user` table. Configure:
|
|
73
|
-
|
|
74
|
-
```ts
|
|
75
|
-
admin({
|
|
76
|
-
defaultRole: "user", // every end-user
|
|
77
|
-
adminRoles: ["owner", "editor", "contributor"], // our existing staff vocabulary
|
|
78
|
-
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
`ensureBootstrapOwner` becomes a `databaseHooks.user.create.after` that promotes the first user matching `ADMIN_GITHUB_LOGIN` to `owner` if no other admin role exists yet. The `staff` D1 table, `D1StaffRepository`, `StaffRepository` port, and `runtime.staff` are deleted.
|
|
82
|
-
|
|
83
|
-
The manifest grammar predicate `requires.auth.all: [{ "ctx.staff": ["editor"] }]` evaluates against `session.user.role` at runtime. Closed enum membership unchanged.
|
|
84
|
-
|
|
85
|
-
### 3. Two explicit MCP surfaces
|
|
86
|
-
|
|
87
|
-
`/mcp` and `/staff/mcp` are mounted side-by-side from boot. `/staff/mcp`
|
|
88
|
-
exposes staff authoring/lifecycle tools and `/mcp` exposes declared public
|
|
89
|
-
Views and Procedures. An MCP Trigger explicitly chooses `surface: public |
|
|
90
|
-
staff`; the target's `requires.auth` still gates every call.
|
|
91
|
-
|
|
92
|
-
Tool partition rules:
|
|
93
|
-
|
|
94
|
-
- Per-collection auto-emitted authoring tools (`create_draft_<schema>`, `update_draft_<schema>`) — predicate baked-in to require `ctx.staff: [contributor+]`; route to `/staff/mcp`
|
|
95
|
-
- `list_entries` / `get_entry` / `request_publish` / `archive_entry` / `unpublish_entry` — staff-only (return drafts, mutate state); `/staff/mcp` only
|
|
96
|
-
- `query_view_<name>` follows `View.spec.surface`.
|
|
97
|
-
|
|
98
|
-
### 4. Scope-aware DCR via Better Auth `oauthProvider`
|
|
99
|
-
|
|
100
|
-
Better Auth's `oauthProvider` plugin handles DCR. Configure:
|
|
101
|
-
|
|
102
|
-
```ts
|
|
103
|
-
oauthProvider({
|
|
104
|
-
scopes: ["mcp:staff", "mcp:read"],
|
|
105
|
-
clientRegistrationDefaultScopes: ["mcp:read"],
|
|
106
|
-
clientRegistrationAllowedScopes: ["mcp:staff", "mcp:read"],
|
|
107
|
-
validAudiences: [
|
|
108
|
-
"https://<worker>/staff/mcp",
|
|
109
|
-
"https://<worker>/mcp",
|
|
110
|
-
],
|
|
111
|
-
consentPage: "/auth/consent",
|
|
112
|
-
customAccessTokenClaims: ({ user, scopes }) => ({
|
|
113
|
-
role: user.role,
|
|
114
|
-
}),
|
|
115
|
-
})
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
Consent UI semantics:
|
|
119
|
-
|
|
120
|
-
- `mcp:staff` requested — only admin-role users can approve. Non-admin sessions see "you need to be staff to grant this scope."
|
|
121
|
-
- `mcp:read` requested — any signed-in user can approve.
|
|
122
|
-
- Mixed `["mcp:staff", "mcp:read"]` — admin-role users grant both; non-admin users grant only `mcp:read` with a notice.
|
|
123
|
-
|
|
124
|
-
The consent page (`/auth/consent`) is consumer-rendered; SDK ships a minimal HTML fallback for starters that don't customize.
|
|
125
|
-
|
|
126
|
-
Each MCP route validates token scope at request time via `auth.api.getMcpSession()`:
|
|
127
|
-
|
|
128
|
-
- `/staff/mcp` requires `mcp:staff` ∈ session.scopes
|
|
129
|
-
- `/mcp` requires `mcp:read` ∈ session.scopes (`mcp:staff` accepted as superset)
|
|
130
|
-
|
|
131
|
-
The Better Auth MCP plugin exposes the RFC 9728 protected-resource metadata document at the auth mount (`/api/auth/.well-known/oauth-protected-resource` in the Cloudflare starter). Both `/staff/mcp` and `/mcp` point unauthenticated clients at that metadata document through `WWW-Authenticate`.
|
|
132
|
-
|
|
133
|
-
### 5. Role checked dynamically, not embedded in token
|
|
134
|
-
|
|
135
|
-
The token can carry `role` via `customAccessTokenClaims` for caller convenience, but the **MCP route validators always re-read `user.role` fresh** via the session. Cost: ~1ms D1 lookup per request (Better Auth's session cache absorbs most of this). Win: a demoted user is locked out immediately, not at token expiry. Same pattern for the consent UI staff gate.
|
|
136
|
-
|
|
137
|
-
### 6. Single auth surface, no port indirection
|
|
138
|
-
|
|
139
|
-
Auth is no longer an adapter port. `mantle-runtime` does NOT define an auth port and `createCmsRuntime()` does not accept auth. Adapter packages construct the Better Auth instance with the right database adapter for their platform and keep it in the adapter-owned HTTP/MCP mount layer.
|
|
140
|
-
|
|
141
|
-
The adapter uses Better Auth to validate sessions, MCP bearer tokens, scopes, and roles, then passes authenticated user/staff context into runtime dispatchers. Better Auth remains platform-agnostic, but it is not a runtime dependency.
|
|
142
|
-
|
|
143
|
-
This is a minor amendment to ADR-0011 (adapter port spec): the auth ports disappear and auth becomes adapter-owned mount wiring. The hard invariant ("`mantle-runtime` MUST NOT import `D1Database` / `KVNamespace`") is preserved.
|
|
144
|
-
|
|
145
|
-
### 7. Auth as contract, Better Auth as default
|
|
146
|
-
|
|
147
|
-
**Amended 2026-05-14.** The seven auth-cascade PRs (#160 / #161 / #162 / #165 / #167 / #169 / #173) shipped Better Auth-backed config + admin SPA + tests. During that work two architectural lines need to be explicit so future PRs don't drift toward mechanical pass-through:
|
|
148
|
-
|
|
149
|
-
**The SDK's public auth contract is the `Auth` interface, not Better Auth.**
|
|
150
|
-
|
|
151
|
-
`packages/adapters/cloudflare/src/auth/createAuth.ts` exports:
|
|
152
|
-
|
|
153
|
-
```ts
|
|
154
|
-
export interface Auth {
|
|
155
|
-
readonly handler: (request: Request) => Promise<Response>;
|
|
156
|
-
readonly getSession: (request: Request) => Promise<{...} | null>;
|
|
157
|
-
readonly getMcpSession: (request: Request) => Promise<{...} | null>;
|
|
158
|
-
readonly getUserRole: (userId: string) => Promise<string | null>;
|
|
159
|
-
readonly methods: ReadonlyArray<AuthMethodInfo>;
|
|
160
|
-
}
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
The internal consumers of `Auth` (post-#193: `mountServerEndpoints`, `createMcpApiHandler`, `mountAuthorize`, `bootRuntimeOnce`, `cmsConfig`) all import only the `Auth` type — never `betterAuth`, never any plugin internals. Better Auth is imported in exactly one file (`createAuth.ts`).
|
|
164
|
-
|
|
165
|
-
**`createAuth(config)` is the SDK-shipped, Better Auth-backed *default* implementation.** Adopters who want the curated `methods[]` shape, `bootstrapOwner` promotion, Workers-aware rate-limit, fire-and-forget `backgroundTasks.handler`, `extras` reserved-key validation, and the `Auth.methods` admin-SPA contract — pass a config to `createAuth()` and get an `Auth`.
|
|
166
|
-
|
|
167
|
-
**Adopters who want a different backend implement `Auth` directly and bypass `createAuth`.** Lucia, Auth.js, a custom hand-roll — all valid. The seam already works today; the `/api/auth/*` URL convention (which Better Auth picks for its mounted endpoints) is a second-tier contract that affects the admin SPA. `auth-views.tsx` hard-codes six paths today (`/api/auth/methods`, `/api/auth/sign-in/social`, `/api/auth/email-otp/send-verification-otp`, `/api/auth/sign-in/email-otp`, `/api/auth/sign-in/magic-link`, `/api/auth/sign-out`); replacing the backend means matching the URL convention OR forking `auth-views.tsx`.
|
|
168
|
-
|
|
169
|
-
**Anti-pattern to refuse in review: Better Auth-field pass-through.**
|
|
170
|
-
|
|
171
|
-
> **Narrowed by the 2026-09-22 amendment** for `OAuthProviderConfig.extensions`, Better Auth's declared OAuth-provider composition point. See § "2026-09-22 amendment" below.
|
|
172
|
-
|
|
173
|
-
If a future PR's only effect is to rename a Better Auth field into our `CreateAuthConfig` and forward it verbatim, refuse it. **Picking a different literal default for an existing Better Auth field does NOT, by itself, justify a new field on `CreateAuthConfig` — that's the same pass-through dressed up.** The SDK adds load-bearing surface area only when the new field exists for at least one of these concrete reasons:
|
|
174
|
-
|
|
175
|
-
- **Workers-aware behavior** that Better Auth doesn't supply (e.g. `rateLimit` flipped on by default when an email-shaped method registers — Better Auth's per-route limits gate on `process.env.NODE_ENV === "production"` which is unset on Workers; `advanced.backgroundTasks.handler` wired to fire-and-forget — closes the timing-oracle on OTP send).
|
|
176
|
-
- **Cross-adapter port** the runtime needs (e.g. `EmailSender` in `mantle-runtime/domain/port/` — used by both `createAuth`'s OTP / magic-link callbacks AND future use cases like order receipts).
|
|
177
|
-
- **Safety net** Better Auth doesn't provide (e.g. `extras` reserved-key validation refuses to let an adopter shadow `clientSecret` via spread order; bootstrap-method cross-check refuses `match: "github-login"` with no `github` social registered).
|
|
178
|
-
- **New abstraction** that fuses multiple Better Auth surfaces (e.g. `methods[]` unifies `socialProviders` + `emailOTP` + `magicLink` plugins under one config shape with shared per-method discrimination).
|
|
179
|
-
- **DX helper that removes a Workers-hostile dep** (e.g. `appleClientSecret` signs the ES256 JWT via `crypto.subtle` so adopters don't have to install `jose` for the one task Better Auth's docs assume a JWT lib).
|
|
180
|
-
|
|
181
|
-
A different default value on its own is not on this list. Default tweaks live in adopter code.
|
|
182
|
-
|
|
183
|
-
> **Retracted by Amendment 2026-05-15.** This section originally pointed at a `CreateAuthConfig.betterAuthOptions?: Partial<BetterAuthOptions>` escape hatch (introduced in PR #175). The 2026-05-15 OAuth carve-out (PR #193) removed it. With the MCP OAuth surface now served by `@cloudflare/workers-oauth-provider`, the un-curated knob set Better Auth still owns (staff sign-in, social, OTP, magic-link, role) is small enough that the curated `methods[]` / `rateLimit` / `bootstrapOwner` fields cover the adopter contract. When a missing Better Auth knob is real and load-bearing, the answer is a curated first-class field — not a passthrough. See § "Amendment 2026-05-15" below.
|
|
184
|
-
|
|
185
|
-
This makes the implicit explicit. The SDK's auth surface is committee-curated; un-curated knobs require either a justified first-class field or an architectural change to remove the dependency on that knob.
|
|
186
|
-
|
|
187
|
-
### 8. Path to `@aotter/mantle-better-auth` separate package (deferred)
|
|
188
|
-
|
|
189
|
-
Each adapter owns its Better Auth wiring. Today the seam is:
|
|
190
|
-
|
|
191
|
-
- `Auth` interface lives in the adapter (could move to runtime or a separate package without breaking the contract — adapters consume the type, not the implementation).
|
|
192
|
-
- `createAuth.ts` is the only file with `import { betterAuth }` (~290 LOC, no Cloudflare-binding-specific code outside `config.database: D1Database`).
|
|
193
|
-
- `ConsoleEmailSender.ts` is dev-only and platform-agnostic (~25 LOC).
|
|
194
|
-
- `appleClientSecret.ts` uses Web Crypto (`crypto.subtle`) which Workers + Node 18+ + Bun + Deno all share (~150 LOC).
|
|
195
|
-
|
|
196
|
-
The future split looks like:
|
|
197
|
-
|
|
198
|
-
```
|
|
199
|
-
@aotter/mantle-runtime ← ports + use cases (today)
|
|
200
|
-
@aotter/mantle-better-auth ← createAuth + EmailSender impls + appleClientSecret (new, when needed)
|
|
201
|
-
@aotter/mantle-cloudflare ← Workers adapter; depends on (or accepts) Auth-shape (today)
|
|
202
|
-
future adapter ← same contract, implemented when needed
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
The pivot point — when to extract — is when a second adapter needs the same wiring. Until then, in-place co-location is cheaper than a new package boundary.
|
|
206
|
-
|
|
207
|
-
## Consequences
|
|
208
|
-
|
|
209
|
-
### What gets deleted
|
|
210
|
-
|
|
211
|
-
- `packages/adapters/cloudflare/src/oauth/` entire directory (`githubOAuth.ts`, `consentHtml.ts`, `oauthSingleton.ts`, `oauthConstants.ts`, `index.ts`)
|
|
212
|
-
- `packages/adapters/cloudflare/src/bindings/D1UserRepository.ts`
|
|
213
|
-
- `packages/adapters/cloudflare/src/bindings/D1SessionRepository.ts`
|
|
214
|
-
- `packages/adapters/cloudflare/src/bindings/D1StaffRepository.ts`
|
|
215
|
-
- `packages/adapters/cloudflare/src/bindings/WorkersOAuthVerifier.ts`
|
|
216
|
-
- `packages/adapters/cloudflare/src/bindings/StubOAuthVerifier.ts`
|
|
217
|
-
- `mantle-runtime/src/domain/port/UserRepository.ts`
|
|
218
|
-
- `mantle-runtime/src/domain/port/SessionRepository.ts`
|
|
219
|
-
- `mantle-runtime/src/domain/port/StaffRepository.ts`
|
|
220
|
-
- `mantle-runtime/src/domain/port/OAuthVerifier.ts`
|
|
221
|
-
- `mantle-runtime/src/runtime.ts` `users` / `sessions` / `staff` / `oauth` ports
|
|
222
|
-
- `mountServerEndpoints.ts` `/admin/auth/github` + callback (Better Auth handles), session cookie read/write code, `ensureBootstrapOwner` inline logic (moves to hook), OAuth consent UI handlers (`/oauth/authorize` GET/POST), OAuth provider passthrough (`/oauth/token`, `/oauth/register`, `.well-known/*`)
|
|
223
|
-
- D1 tables: `users`, `social_logins`, `sessions`, `github_tokens`, `staff`
|
|
224
|
-
- `OAUTH_KV` binding (no longer required in `wrangler.toml`)
|
|
225
|
-
- `@cloudflare/workers-oauth-provider` dependency
|
|
226
|
-
|
|
227
|
-
### What stays
|
|
228
|
-
|
|
229
|
-
- `mount/mountMcp.ts` — refactored to mount both `/mcp` + `/staff/mcp`, validates via `auth.api.getMcpSession()`, and enforces route scopes.
|
|
230
|
-
- `infrastructure/mcp/McpJsonRpcDispatcher.ts` — refactored to support staff vs public tool catalogs.
|
|
231
|
-
- All entries / publish / view machinery (zero auth-related changes)
|
|
232
|
-
- Admin SPA — sign-in view rewritten to redirect to Better Auth route; identity / role queries use Better Auth client
|
|
233
|
-
|
|
234
|
-
### What gets added
|
|
235
|
-
|
|
236
|
-
- Better Auth library + Kysely + `kysely-d1` packages (or whichever D1 adapter Better Auth recommends current)
|
|
237
|
-
- Better Auth instance at `packages/adapters/cloudflare/src/auth/createAuth.ts` (factory taking env / D1 binding)
|
|
238
|
-
- New `EmailSender` port + `ResendEmailSender` adapter impl (used by Better Auth `magicLink` / `emailOTP` plugins)
|
|
239
|
-
- `databaseHooks.user.create.after` for `ensureBootstrapOwner` semantics
|
|
240
|
-
- Two `/.well-known/oauth-protected-resource/*` metadata endpoints (Better Auth helpers)
|
|
241
|
-
- Public View MCP tools: dispatcher emits `query_view_<name>` on `/mcp`.
|
|
242
|
-
- Skills + docs updates for the dual MCP URL handoff
|
|
243
|
-
|
|
244
|
-
### Backward compatibility
|
|
245
|
-
|
|
246
|
-
None. Pre-v0.1.0 has no external consumers. Existing demo deployments tear down + re-bootstrap from the migrated `0.0.x-alpha` release.
|
|
247
|
-
|
|
248
|
-
### Skills + launch handoff
|
|
249
|
-
|
|
250
|
-
The Mantle landing launch session and generated repo-local
|
|
251
|
-
`mantle:provision` skill document the dual MCP handoff. Provision's final
|
|
252
|
-
report distinguishes:
|
|
253
|
-
|
|
254
|
-
```
|
|
255
|
-
Public site: https://<worker>.workers.dev/
|
|
256
|
-
Staff MCP URL: https://<worker>.workers.dev/mcp/staff (give to your owner agent)
|
|
257
|
-
User MCP URL: https://<worker>.workers.dev/mcp (give to visitors / their agents)
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
The publication starter repo's production smoke recipe uses `/mcp/staff`
|
|
261
|
-
for the MCP operator smoke step.
|
|
262
|
-
|
|
263
|
-
### Platform agnosticism
|
|
264
|
-
|
|
265
|
-
By removing `@cloudflare/workers-oauth-provider` and routing auth through Better Auth, the SDK no longer depends on any CF-specific auth service. A future adapter can construct Better Auth against its database while the runtime + dispatcher + skills + prompts stay unchanged. ADR-0011 (adapter port spec) is amended: the `OAuthVerifier` port disappears; auth becomes adapter-owned, with platform-agnostic Better Auth as the type.
|
|
266
|
-
|
|
267
|
-
## Alternatives considered
|
|
268
|
-
|
|
269
|
-
### Alt-A: Hand-rolled multi-IDP without a library
|
|
270
|
-
|
|
271
|
-
Continue the existing `oauth/githubOAuth.ts` pattern, write `googleOAuth.ts` and `appleOAuth.ts`, wire account-linking by hand, keep `workers-oauth-provider` for DCR.
|
|
272
|
-
|
|
273
|
-
**Rejected** — Apple Sign In's JWT-signed client secret rotation (every 6 months) is non-trivial; account-linking with reauth flow has security pitfalls; magic-link / email-OTP adds 200+ LOC of token storage + send + verify per flow. Total scope is ~1500 LOC of auth code for v0.2. Better Auth covers this with config + plugins.
|
|
274
|
-
|
|
275
|
-
### Alt-B: arctic library for upstream IDPs, keep `workers-oauth-provider` for DCR
|
|
276
|
-
|
|
277
|
-
Use [arctic](https://arcticjs.dev) for upstream IDP clients, keep our existing `users` / `social_logins` / `sessions` / `staff` schema, hand-roll session management + account linking + magic link, retain `workers-oauth-provider`.
|
|
278
|
-
|
|
279
|
-
**Rejected** — arctic only solves the OAuth client step (~150 LOC saved). Session management, role machinery, account linking with reauth, magic-link plugin — all still hand-rolled. `workers-oauth-provider` retained means we still glue two systems. Compared to Better Auth (which absorbs all of these into one), arctic forces more glue code AND keeps the platform coupling.
|
|
280
|
-
|
|
281
|
-
### Alt-C: Better Auth for upstream IDPs, keep `workers-oauth-provider` for DCR
|
|
282
|
-
|
|
283
|
-
Adopt Better Auth as identity / session / role authority. Keep `workers-oauth-provider` because it's a known-good DCR implementation.
|
|
284
|
-
|
|
285
|
-
**Rejected as of 2026-05-09** — initial draft of this ADR took this position. Web research showed Better Auth's `oauthProvider` and `mcp` plugins cover the DCR concern with full RFC 7591 / 7662 / 7009 / 9728 compliance. Keeping `workers-oauth-provider` would mean two systems sharing user identity but with different cookie / token / session caches — operationally messier than a single auth surface. The platform-agnosticism win (no CF-specific auth lib) tips the balance.
|
|
286
|
-
|
|
287
|
-
### Alt-D: Single `/mcp` with role + scope flags
|
|
288
|
-
|
|
289
|
-
Keep one MCP route. Gate with config flags: `mcpRequiresStaff`, `mcpAllowEndUser`, scope checks per tool.
|
|
290
|
-
|
|
291
|
-
**Rejected** — flag combinatorics explode as we add subscription tiers + per-collection visibility. Two routes derived from manifest predicate eliminates the flag matrix entirely; the rule is reviewable as a single sentence.
|
|
292
|
-
|
|
293
|
-
### Alt-E: Two separate Better Auth `oauthProvider` instances
|
|
294
|
-
|
|
295
|
-
One DCR provider for staff MCP, one for end-user MCP.
|
|
296
|
-
|
|
297
|
-
**Rejected** — two consent UIs, two token tables, double the configuration burden, no real benefit. Single auth server with scope-based gating achieves the same separation cleanly per the OAuth spec.
|
|
298
|
-
|
|
299
|
-
### Alt-F: `staff` table preserved alongside Better Auth user table
|
|
300
|
-
|
|
301
|
-
Keep our `staff` overlay and `D1StaffRepository`. Use Better Auth only for identity / session / account, route role machinery through staff overlay.
|
|
302
|
-
|
|
303
|
-
**Rejected** — duplicate role data (Better Auth `admin` plugin + our staff overlay) is worse than picking one. Audit trail is the only thing the standalone overlay buys, and v0.1.0 doesn't need it.
|
|
304
|
-
|
|
305
|
-
## Implementation status (historical snapshot)
|
|
306
|
-
|
|
307
|
-
Phase 0 (spike, 0.5–1d) — pending:
|
|
308
|
-
|
|
309
|
-
- Confirm Better Auth + `admin` plugin + `oauthProvider` (or `mcp`) plugin operational on D1 in Workers
|
|
310
|
-
- Confirm Better Auth's auto-mounted `.well-known/oauth-authorization-server` is reachable
|
|
311
|
-
- Confirm two `.well-known/oauth-protected-resource/*` metadata documents serve correctly (helper or hand-roll)
|
|
312
|
-
- Confirm DCR clients (Claude Code, Cursor) follow RFC 9728 path-prefix metadata
|
|
313
|
-
- Confirm `auth.api.getMcpSession()` validates bearer tokens at the protected-resource path
|
|
314
|
-
- Confirm `auth.api.getSession()` works inside consumer routes
|
|
315
|
-
- Bundle size delta on the worker
|
|
316
|
-
|
|
317
|
-
Phase 1 (migration, ~2d) — pending Phase 0:
|
|
318
|
-
|
|
319
|
-
- Better Auth integration (publication starter + mantle-cloudflare adapter)
|
|
320
|
-
- Schema cut-over (canonical migrations rewrite, drop legacy auth tables, add Better Auth tables)
|
|
321
|
-
- Drop `oauth/` directory, all auth ports, `WorkersOAuthVerifier`, `StubOAuthVerifier`
|
|
322
|
-
- Drop `@cloudflare/workers-oauth-provider` dep + `OAUTH_KV` binding
|
|
323
|
-
- Mount factories rewrite (`mountServerEndpoints` for admin gate, `mountMcp` for dual-route)
|
|
324
|
-
- Dispatcher refactor (per-tool surface routing from manifest predicate)
|
|
325
|
-
- Tests update (`mcp-smoke` → `staff-mcp-smoke` + new `public-mcp-smoke`)
|
|
326
|
-
- Skills + prompts + starter README updates
|
|
327
|
-
- Admin SPA sign-in view rewrite
|
|
328
|
-
|
|
329
|
-
Phase 2 (v0.1.x):
|
|
330
|
-
|
|
331
|
-
- Enable Google + Apple `socialProviders` (config-only — Apple needs Apple Developer cert setup which is consumer-side)
|
|
332
|
-
- Magic-link + email-OTP plugins enabled (need `ResendEmailSender` wired)
|
|
333
|
-
- Account-linking with reauth UI in publication starter
|
|
334
|
-
|
|
335
|
-
## How to apply
|
|
336
|
-
|
|
337
|
-
When reviewing or implementing a change that touches auth, MCP routing, or roles:
|
|
338
|
-
|
|
339
|
-
1. **Identity and local sessions** — depend on the adapter's public `Auth`
|
|
340
|
-
interface. `createAuth()` is the curated Better Auth-backed Cloudflare
|
|
341
|
-
default; do not import Better Auth internals outside that implementation or
|
|
342
|
-
add an un-curated passthrough.
|
|
343
|
-
2. **Mutable staff privilege** — call `auth.getUserRole(userId)` on every
|
|
344
|
-
protected REST/MCP invocation. Do not trust a role captured in an OAuth
|
|
345
|
-
grant or long-lived token.
|
|
346
|
-
3. **MCP transport** — export `createOAuthProvider(...)` at the Worker top
|
|
347
|
-
level. It owns DCR/PKCE/token verification and dispatches `/mcp` and
|
|
348
|
-
`/mcp/staff`; the consent handler uses the current local `Auth` session.
|
|
349
|
-
4. **MCP surface** — use explicit `View.spec.surface` and
|
|
350
|
-
`Trigger.source.surface`. The adapter pre-filters each catalog; the shared
|
|
351
|
-
runtime evaluator then enforces the target's `requires.auth.all` and
|
|
352
|
-
optional guard on every call.
|
|
353
|
-
5. **Scopes and props** — advertise the compatibility scope `mcp`. Store only
|
|
354
|
-
immutable grant identity (`userId`, `clientId`, scopes); never store mutable
|
|
355
|
-
staff role or raw/refresh tokens in runtime context.
|
|
356
|
-
6. **REST credentials** — normalize sessions, OAuth JWTs, and an optional
|
|
357
|
-
consumer `credentialResolver` into `HandlerContext`. A recognized invalid
|
|
358
|
-
API key/PAT fails closed and never falls back to a cookie. Standard remote
|
|
359
|
-
MCP does not promise raw REST key/PAT support.
|
|
360
|
-
7. **Adapter portability** — auth remains adapter-owned. A future adapter
|
|
361
|
-
verifies its platform's credentials and supplies the same normalized
|
|
362
|
-
runtime context; `mantle-runtime` does not gain a Better Auth dependency or
|
|
363
|
-
an auth storage port.
|
|
364
|
-
|
|
365
|
-
## Sources
|
|
366
|
-
|
|
367
|
-
- [Better Auth MCP plugin docs](https://better-auth.com/docs/plugins/mcp)
|
|
368
|
-
- [Better Auth OAuth 2.1 Provider plugin docs](https://better-auth.com/docs/plugins/oauth-provider)
|
|
369
|
-
- [Better Auth admin plugin docs](https://better-auth.com/docs/plugins/admin)
|
|
370
|
-
- [Better Auth changelog (1.5+)](https://better-auth.com/blog/1-5)
|
|
371
|
-
- [RFC 7591 — Dynamic Client Registration](https://datatracker.ietf.org/doc/html/rfc7591)
|
|
372
|
-
- [RFC 9728 — Protected Resource Metadata](https://datatracker.ietf.org/doc/html/rfc9728)
|
|
373
|
-
|
|
374
|
-
## Amendment — 2026-05-15: MCP carve-out to `@cloudflare/workers-oauth-provider`
|
|
375
|
-
|
|
376
|
-
Empirical follow-up to the §"Decision" record above. After shipping the Better Auth `mcp()`-plugin path through `0.0.8-beta.5`, Claude Desktop and claude.ai (web) consistently failed at the OAuth handover even though the server-side dance was RFC-correct (DCR + PKCE + AS metadata + PRM all verified via `wrangler tail`). The Anthropic-side error always surfaced as a generic `ofid_*` reference; `/token` returned 200, then the MCP client never made the post-OAuth `/staff/mcp` POST.
|
|
377
|
-
|
|
378
|
-
We built an isolated POC worker (`the deleted MCP POC worker`, since deleted) that ran `@cloudflare/workers-oauth-provider` at top level with a single dummy `echo` MCP tool. The POC connected to claude.ai cleanly. Migrating the same pattern back to `the legacy MCP test deployment`, three constraints were narrowed:
|
|
379
|
-
|
|
380
|
-
1. **MCP resource path must start with `/mcp`.** `/staff/mcp` fails (claude.ai drops the session after a server-correct `/token` success). `/mcp/staff` works. Probably an Anthropic-side URL pattern check from an early MCP draft; not currently documented in any spec we found.
|
|
381
|
-
2. **`scopes_supported` must not contain colons.** Advertising `["mcp:read", "mcp:staff"]` causes claude.ai to silently omit `scope=` from `/authorize`, yielding a zero-scope token grant that the client then rejects post-token. Single `["mcp"]` works. Per-surface differentiation moves server-side: staff role is checked in the apiHandler via D1 `getUserRole`, not via OAuth scope.
|
|
382
|
-
3. **OAuth provider must be top-level worker entry.** `export default new OAuthProvider({...})` is required so the lib intercepts `/.well-known/oauth-*` + `/oauth/{authorize,token,register}` + `apiRoute(s)` before forwarding to `defaultHandler` (Hono). Side-mounting from inside Hono left the lib unable to inject `env.OAUTH_PROVIDER` for the consent handler.
|
|
383
|
-
|
|
384
|
-
### Architectural change
|
|
385
|
-
|
|
386
|
-
| Concern | Before (ADR-0014 §Decision) | After (this amendment) |
|
|
387
|
-
|---|---|---|
|
|
388
|
-
| Staff sign-in | Better Auth `admin` + social providers | Same — unchanged |
|
|
389
|
-
| Session / user / role | Better Auth D1 tables | Same |
|
|
390
|
-
| MCP OAuth AS surface | Better Auth `mcp()` plugin (opaque tokens, no JWKS) | `@cloudflare/workers-oauth-provider` (KV grants, lib-internal token format) |
|
|
391
|
-
| MCP endpoints | `/staff/mcp` + `/mcp` mounted in Hono with `auth.api.getMcpSession()` | `/mcp/staff` + `/mcp` registered as `apiHandlers` on the top-level OAuthProvider; lib verifies bearer + sets `ctx.props` |
|
|
392
|
-
| Scope | `mcp:staff` + `mcp:read` colon-namespaced | Single `["mcp"]` advertised; staff gating via D1 role lookup |
|
|
393
|
-
| `auth.getMcpSession()` | Part of the SDK `Auth` interface | Removed; the OAuth lib owns token verification |
|
|
394
|
-
| Consent UI | Better Auth's built-in | Adapter-mounted on Hono via `mountAuthorize`; reads `c.env.OAUTH_PROVIDER` helpers the lib injects, gates on `auth.getSession()` |
|
|
395
|
-
| URL conventions | `/api/auth/mcp/*` | `/oauth/*` — namespaced (not bare) to avoid squatting on generic root paths |
|
|
396
|
-
|
|
397
|
-
### Why Better Auth still wins the auth-side concerns
|
|
398
|
-
|
|
399
|
-
The split is clean because the two libs answer different questions:
|
|
400
|
-
|
|
401
|
-
- **Better Auth** answers "who logged into our backstage console?" — sign-in flows, social providers, session cookie, user/role state in D1.
|
|
402
|
-
- **workers-oauth-provider** answers "how do we authorize a third-party OAuth client (MCP) to act on a backstage user's behalf?" — DCR, PKCE, consent, token issue, KV grant store.
|
|
403
|
-
|
|
404
|
-
Removing Better Auth would force re-implementing all of (a) and gains nothing — Better Auth is uncontested for the staff sign-in surface. Removing workers-oauth-provider would force re-implementing all of (b) and was tried via Better Auth's `mcp()` plugin; the result didn't reach Anthropic-client compatibility within reasonable iterations.
|
|
405
|
-
|
|
406
|
-
### Auth-as-contract is preserved without the escape hatch
|
|
407
|
-
|
|
408
|
-
The companion `CreateAuthConfig.betterAuthOptions?: Partial<BetterAuthOptions>` escape hatch from PR #175 is **removed**. Empirically it was a contested anti-pattern: the carved-out MCP surface no longer requires per-adopter Better Auth overrides (the OAuth surface is fully delegated), and the remaining adopter-facing knobs are all curated first-class fields on `CreateAuthConfig` (`methods[]`, `rateLimit`, `bootstrapOwner`). If a Better Auth knob is missing from the SDK contract, the answer is a curated first-class field, not the un-curated escape hatch.
|
|
409
|
-
|
|
410
|
-
The original ADR-0014 §"Auth as contract, Better Auth as default" framing stays correct; only the §"Implementation status" reference to `betterAuthOptions` is retracted.
|
|
411
|
-
|
|
412
|
-
### What didn't change
|
|
413
|
-
|
|
414
|
-
- The auth storage port remains removed; the adapter owns `Auth` and passes
|
|
415
|
-
verified, normalized caller context into runtime dispatchers.
|
|
416
|
-
- Apple's `trustedOrigins` auto-append (`https://appleid.apple.com`) and `sameSite=none` cookie injection for cross-site `form_post` callback stay.
|
|
417
|
-
- `appleClientSecret()` helper (from PR #173) stays.
|
|
418
|
-
- All non-OAuth admin endpoints (`/api/auth/*`, `/api/auth/methods`, admin SPA mount) stay on Better Auth.
|
|
419
|
-
- The `bootstrapOwner` + email-OTP + magic-link + `methods[]` carve-out stay.
|
|
420
|
-
|
|
421
|
-
### Compatibility constraints to re-test before changing
|
|
422
|
-
|
|
423
|
-
- Anthropic clients required the `/mcp` resource-path prefix during the
|
|
424
|
-
carve-out verification.
|
|
425
|
-
- Colon-shaped advertised scopes broke the same clients; Mantle therefore
|
|
426
|
-
advertises one `mcp` scope and re-evaluates target authorization server-side.
|
|
427
|
-
|
|
428
|
-
## Amendment — 2026-06-30: Hosted-auth boundary and first-party cookie fields
|
|
429
|
-
|
|
430
|
-
Mantle Platform introduces a first-party hosted-auth use case. Platform owns
|
|
431
|
-
site-owner accounts, billing, entitlement, provider credentials, and managed
|
|
432
|
-
email, while Hosted Auth is an OAuth proxy rather than a member directory.
|
|
433
|
-
Each customer site owns its Better Auth users, linked provider accounts,
|
|
434
|
-
sessions, roles, and grants. For Hosted GitHub, the validated proxy profile's
|
|
435
|
-
`github_login` maps to the existing site-local `user.githubLogin`, so hosted
|
|
436
|
-
and self-managed GitHub reuse the same atomic first-owner bootstrap rule. The
|
|
437
|
-
conventional customer-site path uses the proxy's public OAuth client with PKCE
|
|
438
|
-
and `ADMIN_GITHUB_LOGIN`; it does not use Platform Account OIDC, a client
|
|
439
|
-
secret, or an owner email handoff. The local provider id remains `github`.
|
|
440
|
-
The wire contract remains in [Platform #35](https://github.com/aotter/mantle-platform/issues/35),
|
|
441
|
-
and the product boundary is documented in
|
|
442
|
-
[`docs/auth-hosting-model.md`](https://github.com/aotter/mantle/blob/main/docs/auth-hosting-model.md).
|
|
443
|
-
|
|
444
|
-
This does not change ADR-0014's core rule: Mantle does not expose an
|
|
445
|
-
un-curated `betterAuthOptions` or `advanced` passthrough. Missing Better
|
|
446
|
-
Auth knobs become first-class SDK fields only when a real Mantle use
|
|
447
|
-
case needs them.
|
|
448
|
-
|
|
449
|
-
The first-party SSO use case needs exactly three Better Auth fields:
|
|
450
|
-
|
|
451
|
-
- `trustedOrigins` — app-owned origins that Better Auth should trust for
|
|
452
|
-
auth flows. SDK-managed provider origins, such as Apple, are still
|
|
453
|
-
injected automatically.
|
|
454
|
-
- `crossSubDomainCookies` — Better Auth's same-parent-domain cookie
|
|
455
|
-
support for a trusted first-party app family.
|
|
456
|
-
- `cookiePrefix` — required when two Better Auth apps can write cookies
|
|
457
|
-
under the same parent domain, so Platform cookies do not collide with
|
|
458
|
-
Landing or generated-site cookies.
|
|
459
|
-
|
|
460
|
-
These fields are additive. Existing consumers that do not pass them keep
|
|
461
|
-
the previous cookie/session behavior.
|
|
462
|
-
|
|
463
|
-
The boundary is deliberately narrower than "hosted auth everywhere":
|
|
464
|
-
|
|
465
|
-
- Free users can still self-host every login method Mantle exposes
|
|
466
|
-
through `createAuth()`.
|
|
467
|
-
- Same-parent-domain SSO can use `crossSubDomainCookies` when the same
|
|
468
|
-
party controls all participating subdomains.
|
|
469
|
-
- Customer-owned domains cannot receive `mantle.tools` cookies. Paid
|
|
470
|
-
hosted auth for `customer.com` must use an OAuth/OIDC broker flow:
|
|
471
|
-
Platform authenticates and returns identity; the customer site creates
|
|
472
|
-
its own local session and maps identity into local grants.
|
|
473
|
-
|
|
474
|
-
## Amendment — 2026-07-15: one adapter-owned authorization pipeline
|
|
475
|
-
|
|
476
|
-
Epic #467 extends the auth contract without moving auth into
|
|
477
|
-
`mantle-runtime`. The original adapter-ownership rule remains authoritative:
|
|
478
|
-
Better Auth is the curated Cloudflare default for identity/session/OIDC, and
|
|
479
|
-
`@cloudflare/workers-oauth-provider` remains the compatibility transport for
|
|
480
|
-
remote MCP. Both adapters now normalize verified callers into the same
|
|
481
|
-
runtime context before invoking a target.
|
|
482
|
-
|
|
483
|
-
`HandlerContext` gains an additive optional `auth` member carrying only:
|
|
484
|
-
|
|
485
|
-
```ts
|
|
486
|
-
{
|
|
487
|
-
credential: "session" | "oauth" | "api-key" | "personal-token";
|
|
488
|
-
credentialId: string | null;
|
|
489
|
-
clientId: string | null;
|
|
490
|
-
scopes: readonly string[];
|
|
491
|
-
}
|
|
492
|
-
```
|
|
493
|
-
|
|
494
|
-
Raw keys/tokens and refresh tokens are forbidden in this context. `ctx.user`
|
|
495
|
-
remains the authenticated subject when one exists; `ctx.staff` is a mutable
|
|
496
|
-
privilege overlay and is re-read from D1 for each protected REST/MCP call.
|
|
497
|
-
|
|
498
|
-
The Cloudflare adapter exposes one `ConsumerCredentialResolver` seam for a
|
|
499
|
-
site to recognize and verify its own API-key or personal-token formats. It
|
|
500
|
-
distinguishes `not-handled`, `invalid`, and `verified`; a recognized invalid
|
|
501
|
-
credential never falls back to a cookie. Core adds no credential repository,
|
|
502
|
-
table, issuance API, or runtime auth port.
|
|
503
|
-
|
|
504
|
-
The curated Better Auth facade also adds the OAuth resource primitives needed
|
|
505
|
-
by a generated site acting as a client or provider:
|
|
506
|
-
|
|
507
|
-
- generic OAuth client `resource` is retained across authorization, code
|
|
508
|
-
exchange, and refresh;
|
|
509
|
-
- OAuth provider `validAudiences` constrains minted JWT audiences;
|
|
510
|
-
- `getProviderAccessToken(request, providerId)` uses the current local session
|
|
511
|
-
and returns no refresh token/account row;
|
|
512
|
-
- `verifyOAuthAccessToken()` verifies issuer/JWKS, audience, time claims, and
|
|
513
|
-
scopes, rejects opaque tokens, and preserves the `401`/`403` distinction.
|
|
514
|
-
|
|
515
|
-
REST and MCP transport verification remain adapter-specific. After
|
|
516
|
-
normalization, both call the same runtime auth evaluator and optional guard
|
|
517
|
-
Procedure. Standard remote MCP continues to use its OAuth bearer and the
|
|
518
|
-
single compatibility `mcp` resource scope; manifest scopes are re-evaluated on
|
|
519
|
-
every `tools/call`. MCP does not promise to accept a raw REST API key/PAT.
|
|
520
|
-
|
|
521
|
-
Dynamic membership, billing, and entitlement state remains consumer-owned.
|
|
522
|
-
`requires.guard.procedure` orchestrates a site handler on every invocation but
|
|
523
|
-
does not introduce a Policy atom or an entitlement service. See
|
|
524
|
-
[Guarded API access](../examples/guarded-api.md) for the public API
|
|
525
|
-
and end-to-end examples.
|
|
526
|
-
|
|
527
|
-
## Amendment — 2026-08-22: Better Auth 1.7 MCP and CIMD convergence
|
|
528
|
-
|
|
529
|
-
Issue #734 revisits the 2026-05-15 compatibility carve-out after Better Auth
|
|
530
|
-
1.7 shipped a dedicated `@better-auth/mcp` package, resource-bound JWT grants,
|
|
531
|
-
and the MCP 2026-07-28 Client ID Metadata Document profile. These are the
|
|
532
|
-
missing capabilities that originally forced Mantle to keep a second OAuth
|
|
533
|
-
authority.
|
|
534
|
-
|
|
535
|
-
The Cloudflare adapter now uses one Better Auth instance for staff identity,
|
|
536
|
-
OAuth authorization, consent, client registration/discovery, token issuance,
|
|
537
|
-
and MCP resource verification. `@cloudflare/workers-oauth-provider` and Core's
|
|
538
|
-
`OAUTH_KV` requirement are removed. This amendment supersedes only the
|
|
539
|
-
2026-05-15 transport carve-out; adapter ownership, the curated `Auth` facade,
|
|
540
|
-
fresh D1 staff-role checks, the single `mcp` compatibility scope, and normalized
|
|
541
|
-
`HandlerContext.auth` remain unchanged.
|
|
542
|
-
|
|
543
|
-
### Provider and resource boundary
|
|
544
|
-
|
|
545
|
-
`createAuth` keeps its general OAuth-provider capability and adds MCP as an
|
|
546
|
-
explicit curated mode, implemented by composing `jwt()` and
|
|
547
|
-
`@better-auth/mcp`. It is not replaced by an MCP-only factory and no Better
|
|
548
|
-
Auth passthrough is exposed. Standard Workers bind one canonical protected
|
|
549
|
-
resource, `${PUBLIC_ORIGIN}/mcp`. Both `/mcp` and `/mcp/staff` accept tokens for
|
|
550
|
-
that resource; `/mcp/staff` remains a stricter server-side role projection, not
|
|
551
|
-
a second OAuth audience.
|
|
552
|
-
|
|
553
|
-
The adapter continues to verify and normalize credentials before calling the
|
|
554
|
-
portable runtime. Better Auth imports remain confined to the default
|
|
555
|
-
implementation. A host app may still implement the `Auth` facade or mount its
|
|
556
|
-
own low-level routes; the generated convenience path does not make Better Auth
|
|
557
|
-
a runtime dependency.
|
|
558
|
-
|
|
559
|
-
MCP request verification reuses Better Auth's DPoP binding primitive and its
|
|
560
|
-
database-backed replay store. Bearer JWTs remain valid; a DPoP-bound JWT is
|
|
561
|
-
accepted only with a matching request proof, method, URL, token hash, and
|
|
562
|
-
single-use proof id. Raw-token callers cannot bypass that request boundary.
|
|
563
|
-
|
|
564
|
-
### CIMD is primary; DCR is bounded compatibility
|
|
565
|
-
|
|
566
|
-
The MCP mode composes:
|
|
567
|
-
|
|
568
|
-
```ts
|
|
569
|
-
mcp({ resource, loginPage, consentPage, scopes: ["mcp"], ... })
|
|
570
|
-
cimd({
|
|
571
|
-
fetchClientMetadataResource,
|
|
572
|
-
metadataProfile: "mcp-2026-07-28",
|
|
573
|
-
})
|
|
574
|
-
```
|
|
575
|
-
|
|
576
|
-
Cloudflare's native `fetch` is the metadata transport only when the Worker has
|
|
577
|
-
`global_fetch_strictly_public` enabled. The runtime flag makes the subrequest
|
|
578
|
-
use Cloudflare's public-Internet routing boundary; Better Auth owns URL
|
|
579
|
-
validation, timeout, response limits, redirect refusal, revalidation, and the
|
|
580
|
-
bounded fetch governor. Mantle does not add a DNS resolver, socket HTTP client,
|
|
581
|
-
or generic transport abstraction.
|
|
582
|
-
|
|
583
|
-
Unauthenticated DCR remains enabled only for older MCP clients. Its lifetime
|
|
584
|
-
stays at the removed provider's 90-day default. Better Auth expires confidential
|
|
585
|
-
registration secrets; Mantle additionally prunes only expired ownerless DCR
|
|
586
|
-
rows (`clientDiscoveryId`, user owner, and reference owner all absent) on
|
|
587
|
-
OAuth traffic. CIMD-owned and operator-managed clients are never cleanup
|
|
588
|
-
candidates. Cleanup is storage hygiene: failures are logged and do not turn a
|
|
589
|
-
valid authorization request into an outage. No cron or second registry is
|
|
590
|
-
introduced.
|
|
591
|
-
|
|
592
|
-
Better Auth's `oauthClient` row is the connected-client authority. It retains
|
|
593
|
-
the discovery provenance and validated name, URI, redirect URIs, application
|
|
594
|
-
type, and private server metadata. The consent UI reads only the public
|
|
595
|
-
secret-free projection. Remote client metadata is not copied into portable
|
|
596
|
-
`HandlerContext` or deferred event envelopes.
|
|
597
|
-
|
|
598
|
-
### Breaking migration
|
|
599
|
-
|
|
600
|
-
All Better Auth packages upgrade together to 1.7. The D1 schema adopts account
|
|
601
|
-
issuer identity, resource/client relationships, resource-bound token and
|
|
602
|
-
consent fields, discovery provenance, and replay storage required by the
|
|
603
|
-
installed plugins. Removed `validAudiences` configuration becomes the one
|
|
604
|
-
explicit MCP resource; generic upstream OAuth adopts the 1.7 social sign-in and
|
|
605
|
-
callback contract.
|
|
606
|
-
|
|
607
|
-
This is an alpha breaking migration. KV registrations, grants, and opaque
|
|
608
|
-
tokens are not migrated into D1 because their issuer/resource provenance cannot
|
|
609
|
-
be established safely; MCP clients reconnect through CIMD or DCR. Existing
|
|
610
|
-
pre-1.7 alpha auth databases are reset and re-bootstrapped rather than receiving
|
|
611
|
-
a guessed account issuer backfill.
|
|
612
|
-
|
|
613
|
-
The authorization endpoints consequently move from `/oauth/*` to Better
|
|
614
|
-
Auth's `/api/auth/oauth2/*` discovery-advertised endpoints. No compatibility
|
|
615
|
-
aliases are retained: existing KV client identifiers are invalid after the
|
|
616
|
-
authority change regardless, and standards-compliant clients rediscover the
|
|
617
|
-
new endpoints.
|
|
618
|
-
|
|
619
|
-
### Downstream ownership
|
|
620
|
-
|
|
621
|
-
Starters remove their obsolete OAuth package and `OAUTH_KV` binding while
|
|
622
|
-
retaining `global_fetch_strictly_public`. Landing opts its custom `createAuth`
|
|
623
|
-
construction into the same MCP mode. Landing may keep an `OAUTH_KV` binding for
|
|
624
|
-
its own launch/bootstrap state; that storage is unrelated to the removed Core
|
|
625
|
-
OAuth store and is not renamed by this decision.
|
|
626
|
-
|
|
627
|
-
This amendment adopts the 2026-07-28 CIMD authorization profile only. Updating
|
|
628
|
-
Mantle's JSON-RPC dispatcher to the complete MCP 2026-07-28 transport revision
|
|
629
|
-
is a separate decision.
|
|
630
|
-
|
|
631
|
-
## 2026-09-07 amendment — shared OAuth surfaces and revocation
|
|
632
|
-
|
|
633
|
-
OAuth product UI is not owned by a runtime adapter. `@aotter/mantle-admin`
|
|
634
|
-
owns `MantleOAuthAuth`, the consent/connected-app view models, and
|
|
635
|
-
`handleMantleOAuth(Request) -> Response | null`; `mountMantleOAuth` is a thin
|
|
636
|
-
Hono bridge. The Cloudflare adapter implements protocol actions using the
|
|
637
|
-
same Better Auth instance and D1. Future adapters reuse this contract, not
|
|
638
|
-
Cloudflare-specific UI glue. The old `mountAuthorize` export remains an alias.
|
|
639
|
-
|
|
640
|
-
`@aotter/mantle-admin-ui` owns the React/shadcn sign-in, consent and connected
|
|
641
|
-
apps surfaces, including i18n, theme and submit state. Auth pages initially
|
|
642
|
-
follow the system theme; the light/dark toggle persists an explicit override.
|
|
643
|
-
Connected apps has an Admin page, but managing one's own grants requires only
|
|
644
|
-
a session, never a staff role. The no-assets HTML fallback uses native forms
|
|
645
|
-
without JavaScript or a second implementation of the Admin design system.
|
|
646
|
-
Both mounts retain same-origin mutation checks and private/no-store responses.
|
|
647
|
-
The consent document's CSP permits only the provider-validated callback
|
|
648
|
-
origin for the browser's form redirect; it never trusts an unsigned query.
|
|
649
|
-
|
|
650
|
-
MCP authorization remains session-bound: the JWT's original Better Auth
|
|
651
|
-
session must still exist and be unexpired. Admin sign-out/session expiration
|
|
652
|
-
therefore also ends that session's MCP access. A refresh token is not an
|
|
653
|
-
independent authorization to bypass this check. Staff roles are still read
|
|
654
|
-
fresh on every protected request.
|
|
655
|
-
|
|
656
|
-
Disconnect is scoped to the authenticated user and the selected client. It
|
|
657
|
-
revokes refresh/opaque access tokens, removes pending authorization codes and
|
|
658
|
-
consent rows, and prevents existing JWTs from becoming valid when the client
|
|
659
|
-
is connected again. The verification-create hook captures the consent row ID
|
|
660
|
-
in Better Auth's existing authorization `referenceId`; Better Auth carries it
|
|
661
|
-
through the authorization code and every refresh rotation. MCP JWTs copy that
|
|
662
|
-
reference into `mantle_consent_id`, which must match the active consent row.
|
|
663
|
-
Never look up a new consent at token mint time: doing so could revive a refresh
|
|
664
|
-
lineage whose insertion raced the revoke batch. Same-second reconnect and a
|
|
665
|
-
delayed old refresh row are required regression cases, not clock delays.
|
|
666
|
-
|
|
667
|
-
MCP mode reserves authorization `referenceId` for this grant identity; future
|
|
668
|
-
curated configuration must not also expose Better Auth's `postLogin` reference
|
|
669
|
-
hooks. MCP access requires a persisted user consent, so `skipConsent` and
|
|
670
|
-
`cachedTrustedClients` must not bypass consent for MCP clients.
|
|
671
|
-
|
|
672
|
-
This alpha hotfix requires existing MCP clients to reconnect once: pre-hotfix
|
|
673
|
-
JWTs without the grant claim are rejected immediately. No account/session reset
|
|
674
|
-
is required. The unshipped watermark migration 0008 is removed; its unused
|
|
675
|
-
table in the phsu development database is harmless and is not queried or
|
|
676
|
-
deleted during deployment.
|
|
677
|
-
|
|
678
|
-
## 2026-09-08 amendment — request security boundaries
|
|
679
|
-
|
|
680
|
-
All Admin session mutations use the existing same-origin guard, including
|
|
681
|
-
same-site sibling origins. Admin HTML forbids framing and is private/no-store.
|
|
682
|
-
The SPA also refuses to render in frames, covering direct static-asset URLs
|
|
683
|
-
that bypass the server mount.
|
|
684
|
-
The Admin/auth mounts cap request bodies at 1 MiB using Hono's body limiter;
|
|
685
|
-
HTTP trigger and MCP dispatchers count streamed JSON bytes before parsing and
|
|
686
|
-
return 413 above the same limit. Media bytes continue through direct uploads.
|
|
687
|
-
This intentionally rejects previously accepted larger control-plane payloads.
|
|
688
|
-
|
|
689
|
-
Cloudflare `createAuth` explicitly enables Better Auth rate limits regardless
|
|
690
|
-
of `NODE_ENV`, including the OAuth provider's anonymous registration limit of
|
|
691
|
-
five requests per minute. Only `CF-Connecting-IP` supplies the client key.
|
|
692
|
-
The upstream memory store limits each isolate; deployments needing a shared
|
|
693
|
-
abuse quota must additionally enforce it at ingress. No D1 migration or new
|
|
694
|
-
runtime platform dependency is introduced.
|
|
695
|
-
|
|
696
|
-
Workers must retain initialization work through `ExecutionContext.waitUntil`
|
|
697
|
-
even when the initial challenge finishes or its client disconnects. Schema
|
|
698
|
-
boot precedes OAuth handling. The adapter's static AsyncLocalStorage seeding
|
|
699
|
-
is a version-pinned Better Auth 1.7.2 integration, with accessor-identity
|
|
700
|
-
regression coverage; it does not replace Better Auth's request context.
|
|
701
|
-
Failed Auth initialization evicts only the failed Worker assembly so a later
|
|
702
|
-
request can retry. Non-HTTP callers await Auth initialization with runtime boot;
|
|
703
|
-
HTTP requests anchor it without making public responses depend on Auth health.
|
|
704
|
-
|
|
705
|
-
### 2026-10-05 amendment — Better Auth 1.7.7 schema validation order
|
|
706
|
-
|
|
707
|
-
Issue #1335 upgrades the complete Better Auth family and the nested MCP provider
|
|
708
|
-
override together to 1.7.7. The AsyncLocalStorage integration above is retested
|
|
709
|
-
against that pin. Better Auth now checks schemas eagerly at construction, before
|
|
710
|
-
Mantle's lazy schema convergence. Mantle disables only that automatic timing and
|
|
711
|
-
executes the public `context.explicitSchemaCheck` after convergence, before auth
|
|
712
|
-
handlers or session reads. It also checks when the auth-schema ledger matches,
|
|
713
|
-
so incompatible schema drift fails closed. Failed preparation clears its promise
|
|
714
|
-
for retry. Static/plan-only requests still do not prepare auth tables. No new
|
|
715
|
-
consumer pass-through, Core port or public grammar is added.
|
|
716
|
-
|
|
717
|
-
Existing 1.7.0–1.7.2 databases have a required legacy `account.issuer` that 1.7.7
|
|
718
|
-
no longer writes. Additive convergence preserves it and explicit validation
|
|
719
|
-
refuses it. The database owner performs the documented host-specific constraint
|
|
720
|
-
migration before restart: PostgreSQL drops only NOT NULL, retaining issuer values;
|
|
721
|
-
SQLite requires a reviewed data-preserving table rebuild. Portable Auth does not
|
|
722
|
-
guess the engine or drop/rebuild historical tables. The PostgreSQL upgrade is
|
|
723
|
-
verified on populated old-schema accounts and existing sessions/content.
|
|
724
|
-
|
|
725
|
-
The conventional `/favicon.ico` reflects the configured site icon, but is a
|
|
726
|
-
fallback after consumer routes, not a newly reserved namespace. Existing
|
|
727
|
-
consumer icon routes must continue to work after a package update.
|
|
728
|
-
|
|
729
|
-
## Amendment — 2026-09-14: Host-only control-plane cookies
|
|
730
|
-
|
|
731
|
-
`CreateAuthConfig.hostOnlyCookies` is an opt-in, curated auth field for a
|
|
732
|
-
control plane on a parent domain shared with tenants. It uses native `__Host-`
|
|
733
|
-
cookie names, `Secure`, `Path=/` and no `Domain`; HTTPS is required and enabling
|
|
734
|
-
cross-subdomain sharing at the same time is rejected. Existing defaults and
|
|
735
|
-
Apple's `SameSite=None` requirement remain unchanged. Consumers must treat
|
|
736
|
-
switching cookie names as an explicit sign-in migration, not rewrite request
|
|
737
|
-
or response cookies. This keeps cookie semantics in the auth adapter rather
|
|
738
|
-
than requiring each consumer to wrap Admin, member and OAuth routes.
|
|
739
|
-
|
|
740
|
-
## Amendment — 2026-09-16: deployment KV session reads
|
|
741
|
-
|
|
742
|
-
Cloudflare deployments may pass their deployment-owned KV namespace as
|
|
743
|
-
`CreateAuthConfig.sessionCacheKv`. Better Auth reads sessions from KV while
|
|
744
|
-
keeping the canonical session row in D1. OTP verification remains D1-backed
|
|
745
|
-
and rate limiting remains isolate-local because Workers KV does not provide
|
|
746
|
-
the atomic consume or increment operations those paths require. Auth keys use
|
|
747
|
-
the `better-auth:<store-instance-id>:` prefix so replacing D1 makes the old
|
|
748
|
-
store's cached sessions unreachable while the namespace can still hold Mantle projections.
|
|
749
|
-
Session revocation and user updates use Better Auth's cache invalidation and
|
|
750
|
-
therefore follow Workers KV's propagation model.
|
|
751
|
-
|
|
752
|
-
## 2026-09-18 amendment — one-way email verification storage
|
|
753
|
-
|
|
754
|
-
The curated Cloudflare auth adapter stores email OTPs and magic-link tokens as
|
|
755
|
-
one-way hashes. This is a fixed security boundary, not adopter configuration;
|
|
756
|
-
`createAuth` does not expose Better Auth's plain or encrypted storage options.
|
|
757
|
-
Deploying this change invalidates any unconsumed codes and links created by an
|
|
758
|
-
older deployment. Users request a new code or link; no database migration is
|
|
759
|
-
needed.
|
|
760
|
-
|
|
761
|
-
## 2026-09-18 amendment — native Better Auth method options
|
|
762
|
-
|
|
763
|
-
Issue #924 supersedes only the preceding amendment's “not adopter
|
|
764
|
-
configuration” restriction. Hashed OTP and magic-link storage remains the
|
|
765
|
-
Mantle default, while an explicit official Better Auth `storeOTP` or
|
|
766
|
-
`storeToken` option may override it, including custom hashers/encryption.
|
|
767
|
-
|
|
768
|
-
`createAuth` remains the Worker lifecycle and Mantle integration boundary, but
|
|
769
|
-
does not copy Better Auth's method option unions. Social methods use the
|
|
770
|
-
provider-specific official `SocialProviders` option keyed by `provider`,
|
|
771
|
-
including async factories. Generic OAuth uses `GenericOAuthConfig`; email OTP
|
|
772
|
-
and magic link use their official option types minus the sender callback that
|
|
773
|
-
Mantle owns. GitHub's bootstrap mapper composes with an adopter mapper instead
|
|
774
|
-
of replacing it. Admin method metadata contains only kind, provider id and
|
|
775
|
-
display label, never options or secrets.
|
|
776
|
-
|
|
777
|
-
Applications that need to own an entire callback may pass official plugin
|
|
778
|
-
instances through `plugins`. Those plugins do not synthesize Admin metadata,
|
|
779
|
-
and duplicate plugin ids fail at construction. There is no
|
|
780
|
-
`Partial<BetterAuthOptions>` deep merge and no silent plugin replacement.
|
|
781
|
-
|
|
782
|
-
## 2026-09-21 amendment — keyed default email OTP storage
|
|
783
|
-
|
|
784
|
-
Issue #989 changes only the Mantle default for email OTP storage. Better Auth
|
|
785
|
-
`storeOTP: "hashed"` is unsalted SHA-256 of the OTP. For the default 6-digit
|
|
786
|
-
alphabet that makes a `verification` table dump a sign-in oracle without
|
|
787
|
-
`BETTER_AUTH_SECRET`. The Cloudflare `createAuth` default is now HMAC-SHA-256
|
|
788
|
-
of the OTP keyed by `BETTER_AUTH_SECRET` (unpadded base64url), so D1 alone is
|
|
789
|
-
not enough.
|
|
790
|
-
|
|
791
|
-
Magic-link tokens remain Better Auth `hashed`; they are high-entropy. Explicit
|
|
792
|
-
official `storeOTP` / `storeToken` overrides, including `plain`, remain adopter
|
|
793
|
-
configuration (2026-09-18 native-options amendment / #925). `createAuth` does
|
|
794
|
-
not hard-reject those overrides.
|
|
795
|
-
|
|
796
|
-
Deploying this change invalidates unconsumed OTPs created by an older
|
|
797
|
-
deployment. Users request a new code; no database migration is needed.
|
|
798
|
-
|
|
799
|
-
## Amendment — 2026-09-21: host-neutral `@aotter/mantle-auth`
|
|
800
|
-
|
|
801
|
-
Identity remains adapter-owned: there is still no Core auth port. The Better
|
|
802
|
-
Auth surface is extracted into `@aotter/mantle-auth` (not
|
|
803
|
-
`mantle-better-auth`) ahead of a second-host adapter, because the
|
|
804
|
-
implementation was already host-neutral except for ingress IP headers and
|
|
805
|
-
D1/KV bindings.
|
|
806
|
-
|
|
807
|
-
`createMantleAuth` is the portable constructor. Adapters still own host
|
|
808
|
-
wiring. Cloudflare `createAuth` keeps its existing signature, supplies
|
|
809
|
-
`cf-connecting-ip`, constructs `D1DatabaseDriver`, and optionally wraps
|
|
810
|
-
Workers KV as `AuthSessionCache`. Bun and Vercel have no auth adapter in this
|
|
811
|
-
change; when that wiring lands they must supply their own trusted ingress
|
|
812
|
-
header(s) and driver. The portable package never defaults to a Cloudflare
|
|
813
|
-
header or to client-controlled `X-Forwarded-For`. Missing or empty
|
|
814
|
-
`ipAddressHeaders` fails closed.
|
|
815
|
-
|
|
816
|
-
## 2026-09-21 amendment — instance-level `accountLinking`
|
|
817
|
-
|
|
818
|
-
Issue #952 adds `accountLinking` to `CreateMantleAuthOptions` in the host-neutral
|
|
819
|
-
`@aotter/mantle-auth` package, forwarded verbatim to Better Auth's
|
|
820
|
-
`account.accountLinking`; the Cloudflare `CreateAuthConfig` and every future
|
|
821
|
-
host wrapper inherit it.
|
|
822
|
-
|
|
823
|
-
Issue #924 deferred instance-level control to "a separate low-level instance
|
|
824
|
-
adapter". That deferral is kept for *general* control; this is a single named
|
|
825
|
-
passthrough in the shape `trustedOrigins`, `cookiePrefix` and
|
|
826
|
-
`crossSubDomainCookies` already use, not the option-bag merge #924 rejected.
|
|
827
|
-
The distinction that matters is ambiguity, not nesting depth: a named field
|
|
828
|
-
has one owner and one meaning, while a merged `Partial<BetterAuthOptions>`
|
|
829
|
-
would let an adopter silently overwrite session, cookie and rate-limit
|
|
830
|
-
invariants Mantle enforces.
|
|
831
|
-
|
|
832
|
-
`accountLinking` earned a field ahead of the low-level adapter because it
|
|
833
|
-
decides whether two sign-ins are one person. Mantle cannot pick that default
|
|
834
|
-
on an adopter's behalf — only the adopter knows which providers verify the
|
|
835
|
-
addresses they return — and until now adopters had no way to express it, in
|
|
836
|
-
either direction.
|
|
837
|
-
|
|
838
|
-
Mantle sets no default. Omitted, no `account` key is constructed at all and
|
|
839
|
-
Better Auth's defaults govern: implicit linking on, `requireLocalEmailVerified`
|
|
840
|
-
on, `trustedProviders` empty. A consequence worth stating, because the
|
|
841
|
-
`inviteUser` contract above implies otherwise: an invitation row is written
|
|
842
|
-
`emailVerified: 0`, so a social sign-in cannot claim it until the invitee
|
|
843
|
-
verifies by email once.
|
|
844
|
-
|
|
845
|
-
## 2026-09-21 amendment — one caller gate; surface selects the staff rule only
|
|
846
|
-
|
|
847
|
-
Sections 3 and 5 above describe `/mcp` and `/mcp/staff` as bearer-only routes
|
|
848
|
-
that answer every unauthenticated request with a `401` challenge, while the
|
|
849
|
-
HTTP Trigger and `/api/views/*` routes resolve callers through `resolveCaller`
|
|
850
|
-
(consumer credential, then OAuth bearer, then cookie session, then anonymous)
|
|
851
|
-
and leave enforcement to each target's `requires`. Issue #977 removes that
|
|
852
|
-
split. Both transports now run the same gate (`gateCaller`):
|
|
853
|
-
|
|
854
|
-
- Identity resolution is `resolveCaller` for every transport. A cookie session
|
|
855
|
-
may drive `/mcp` same-origin; the cross-origin guard applies only when the
|
|
856
|
-
credential is a session, as it already did for HTTP mutations.
|
|
857
|
-
- `surface` decides exactly one thing: `staff` requires `ctx.staff`; `public`
|
|
858
|
-
admits anonymous callers. Each tool's `requires.auth` and guard still run on
|
|
859
|
-
every `tools/call`, so a public View with no `requires` is reachable
|
|
860
|
-
anonymously over MCP exactly as it is over REST, and the handbook's
|
|
861
|
-
"the same View is safe on REST and on public MCP" holds.
|
|
862
|
-
- The OAuth bootstrap is preserved where it matters. Invalid credentials and
|
|
863
|
-
anonymous callers on the staff surface still receive `401`/`403` with the
|
|
864
|
-
RFC 9728 `WWW-Authenticate` challenge. On the public surface an anonymous
|
|
865
|
-
`initialize` or `tools/list` succeeds (the catalog is caller-independent), and
|
|
866
|
-
the first `tools/call` whose target requires identity answers HTTP `401` with
|
|
867
|
-
the same challenge instead of an HTTP `200` JSON-RPC error, so a client can
|
|
868
|
-
authenticate mid-session and retry. `AUTH_DENIED` maps to `403` the same way.
|
|
869
|
-
|
|
870
|
-
The fresh-role rule (section 5) and the MCP grant check are unchanged: both
|
|
871
|
-
run inside `resolveCaller`'s bearer path. What changed is only where the
|
|
872
|
-
surface rule sits and that it is the *only* rule the surface adds.
|
|
873
|
-
|
|
874
|
-
Two invariants that the shared gate must keep, stated so they are not lost
|
|
875
|
-
in a later refactor:
|
|
876
|
-
|
|
877
|
-
- **The `mcp` scope floor applies to every presented credential.** Bearer
|
|
878
|
-
tokens are checked inside `resolveCaller`; a consumer credential (site PAT,
|
|
879
|
-
API key) is checked by the MCP handler after the gate, and a PAT minted for
|
|
880
|
-
a narrow integration is refused with `403 insufficient_scope` even when its
|
|
881
|
-
owner is staff. A cookie session carries no scopes and is the same browser
|
|
882
|
-
identity Admin already trusts, so it is exempt. Anonymous callers present
|
|
883
|
-
nothing to check; each tool's `requires` governs them.
|
|
884
|
-
- **JSON-RPC over HTTP is `application/json` only.** The dispatcher answers
|
|
885
|
-
`415` to anything else, so an HTML form (whose enctypes cannot produce that
|
|
886
|
-
header) can never drive a cookie session on `/mcp`; the same-origin guard
|
|
887
|
-
remains the second layer.
|
|
888
|
-
|
|
889
|
-
## 2026-09-22 amendment — OAuth provider extensions are an adopter seam
|
|
890
|
-
|
|
891
|
-
Issue #1016 supersedes the 2026-05-14 "Better Auth-field pass-through"
|
|
892
|
-
prohibition for one field: `OAuthProviderConfig.extensions`, forwarded to
|
|
893
|
-
`@better-auth/oauth-provider`'s `extensions` option. It follows the 2026-09-18
|
|
894
|
-
line that already exposes official Better Auth options and plugin instances
|
|
895
|
-
rather than copying them.
|
|
896
|
-
|
|
897
|
-
Why this is not the refused pattern: an `OAuthProviderExtension` is Better
|
|
898
|
-
Auth's declared composition point for token grants, client-authentication
|
|
899
|
-
strategies, discovery metadata and additional claims. MCP Enterprise-Managed
|
|
900
|
-
Authorization needs a `jwt-bearer` (ID-JAG) grant whose issuer and JWKS belong
|
|
901
|
-
to one enterprise IdP; that is adopter configuration, not an SDK default, and
|
|
902
|
-
Core has no business knowing the issuer. Curating a first-class
|
|
903
|
-
`enterpriseIdp` field would put an IdP contract inside Core and still forward
|
|
904
|
-
it verbatim underneath. The reference implementation lives outside Core
|
|
905
|
-
(`@aotterclam/id-jag`).
|
|
906
|
-
|
|
907
|
-
Boundaries that stay:
|
|
908
|
-
|
|
909
|
-
- Core's own claims extension (`mantle_consent_id`) is always first on the
|
|
910
|
-
`mcpResource` branch; adopter extensions append after it and cannot replace
|
|
911
|
-
it. Better Auth's contract makes claims contributors additive, so an
|
|
912
|
-
extension cannot overwrite identity or AS-owned claims either way.
|
|
913
|
-
- `createMantleAuth` still owns login and consent pages, CIMD/DCR policy,
|
|
914
|
-
`mcpResource`, scopes and resources. `extensions` adds grants and strategies
|
|
915
|
-
beside those; it is not a `Partial<OAuthOptions>` merge and cannot change
|
|
916
|
-
them.
|
|
917
|
-
- Tokens an extension issues go through the provider's shared token path, so
|
|
918
|
-
`verifyOAuthAccessToken`, DPoP binding and the MCP challenge are unchanged.
|
|
919
|
-
- No other Better Auth field gains a passthrough by this amendment. The
|
|
920
|
-
2026-05-14 test still applies to the next proposal.
|
|
921
|
-
|
|
922
|
-
## 2026-10-02 amendment — a surface with no anonymous tool challenges at connect
|
|
923
|
-
|
|
924
|
-
The 2026-09-21 amendment kept anonymous `initialize` and `tools/list` open on the public surface and moved the `401` to
|
|
925
|
-
the first `tools/call` that needs identity. MCP clients do not all follow that: several decide whether to run OAuth from
|
|
926
|
-
the connect step alone (an anonymous `initialize` that succeeds means "no sign-in"), so a surface whose every tool needs
|
|
927
|
-
identity never showed them a sign-in. Better Auth's `withMcpAuth` and the MCP SDK's `requireBearerAuth` both challenge
|
|
928
|
-
every unauthenticated request for the same reason.
|
|
929
|
-
|
|
930
|
-
- A surface is **closed** when none of its tools may be called anonymously: every tool's `requires.auth.all` names at least
|
|
931
|
-
one predicate (each of `ctx.user`, `ctx.auth`, `ctx.staff`, `ctx.auth.scope` needs an identity). The staff surface is
|
|
932
|
-
always closed; a public surface with no tools is open, since nothing on it needs a sign-in.
|
|
933
|
-
- On a closed surface every anonymous request (`initialize`, `tools/list`, the SSE `GET`) answers `401` with the RFC 9728
|
|
934
|
-
`WWW-Authenticate` challenge, as the staff surface already did. The challenge names the surface's scope floor
|
|
935
|
-
(`scope="mcp"` by default), so the first authorization already asks for it.
|
|
936
|
-
- A surface with at least one tool anonymous may call keeps the 2026-09-21 behaviour: discovery stays open and the first
|
|
937
|
-
`tools/call` that needs identity answers `401`.
|
|
938
|
-
- Nothing is configured: the rule follows from the plan, so a project that adds a public tool reopens discovery by
|
|
939
|
-
declaring it.
|