@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,384 +0,0 @@
|
|
|
1
|
-
# ADR-0032: Store-centric Core, an application-owned service, and caller identity
|
|
2
|
-
|
|
3
|
-
**Status:** Accepted for 0.2.0 (#1188). Amends ADR-0014, ADR-0026, ADR-0027 and ADR-0030; storage evolution is decided separately in [ADR-0033](0033-storage-converges-to-the-plan.md). Decisions 1–5, 10 and 13 are amended by [ADR-0034](0034-store-is-authored-as-sql.md): manifests carry SQL, which the CLI compiles to the IR. Decisions 6 and 12 are amended by [ADR-0035](0035-sql-dialects.md).
|
|
4
|
-
|
|
5
|
-
**Date:** 2026-09-27
|
|
6
|
-
|
|
7
|
-
**Related:** #1151 (Store), #1152 (identity), #1156 (table namespace), #1150, #1189, ADR-0022, ADR-0023, ADR-0028, ADR-0031, aotter/mantle-home#201
|
|
8
|
-
|
|
9
|
-
## Context
|
|
10
|
-
|
|
11
|
-
`develop` (3b829e6) carries the first Store slices from ADR-0030, but six persistence paths still generate their own SQL: builtin ops (`EntryRepository`), `store.write` (`AtomicEntryWriter`), legacy Views (`SqliteViewCompiler`), select Views (`SqliteStoreQueryCompiler`), `runtime.entries` (`EntryReader`) and the TTL sweep (`sweepExpired`). Scope, TTL, OCC and hook rules are spread across them, and builtin ops, Admin/MCP CRUD, `EntryReader` and legacy Views ignore `Schema.spec.scope`.
|
|
12
|
-
|
|
13
|
-
The host boundary has the same problem in a different place:
|
|
14
|
-
|
|
15
|
-
- **Mantle owns the entry.** `createMantleWorker` owns the Worker and hands the application a restricted seam (`extend`, `getRuntime`, `MANTLE_RESERVED_PATH_PREFIXES`, `MantleExtensionApp`).
|
|
16
|
-
- **Mantle owns the user.** `0001-init` creates the twelve Better Auth tables on every SQLite database, even without `@aotter/mantle-auth`. `createMantleWorker` requires a full `MantleAuth`, `resolveCaller` calls `getUserRole`, and `mountMantleAdmin` depends on the Better Auth session shape. ChatGPT Sites fakes the Admin methods and hand-mounts Admin.
|
|
17
|
-
- **Cloudflare semantics sit in Core contracts.** ADR-0027 Triggers use Cloudflare's cron dialect and put a required `cloudflare` host in the plan; `HandlerContext.schedule` and `waitUntil` are documented as Cloudflare deliveries.
|
|
18
|
-
|
|
19
|
-
No 0.1.5 has been tagged, and the release is allowed to break grammar, so it ships as 0.2.0.
|
|
20
|
-
|
|
21
|
-
## Decision
|
|
22
|
-
|
|
23
|
-
Spec (the four atoms) compiles into a sealed `RuntimePlan`; Core executes it; everything else is built around Core.
|
|
24
|
-
|
|
25
|
-
```
|
|
26
|
-
application-owned service (MantleHandlers + one WinterTC fetch entry)
|
|
27
|
-
└─ Core: Trigger dispatch → View / Procedure → Store → StoreExecutor
|
|
28
|
-
└ ref → handlers (the only custom code)
|
|
29
|
-
createMantle(service, { storage }) → one fetch; the generated preset wires it into the host's entry
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
### 1. Store is the only path to Mantle-owned entry storage
|
|
33
|
-
|
|
34
|
-
Every entry read and write goes through `MantleStore` / `CallerStore` over the relational JSON IR of ADR-0030. Policies are **IR rewrites applied before storage**: caller scope (including subqueries), TTL visibility, published-only, and OCC (`lock` becomes a version predicate plus `expect: 1`). Storage implementations compile a dialect and apply atomic batches; nothing else.
|
|
35
|
-
|
|
36
|
-
- **Contract.** `select`, `view`, `write` and `id` on both types; `as(caller)` and `sweepExpired` on `MantleStore` only. `as` now takes a `Caller` (decision 7), not a `HandlerContext`.
|
|
37
|
-
- **Write ops** stay `insert | update | delete`, all or nothing. `StoreInsert` gains `onConflict?: "ignore" | { columns, update }` (#1151). `StoreUpdate` and `StoreDelete` both take any `where`, optional `lock` and optional `expect`.
|
|
38
|
-
- **Results.** A row op returns `{ id, version }`; a set op, or an insert ignored by `onConflict`, returns `{ affected }`. `StoreWriteResult` renames `deleted` to `affected`.
|
|
39
|
-
- **Errors** stay `DiagnosticError`: `INPUT_VALIDATION_FAILED`, `CONFLICT`, `RESOURCE_UNAVAILABLE`, `OUTCOME_UNKNOWN` (ADR-0023). `Diagnostic` gains `conflict?: { opIndex?: number; reason: "lock" | "expect" | "unique" }`. `opIndex` is best effort, because a D1 batch cannot report which statement failed.
|
|
40
|
-
- **Status changes** are `update` with `set: { status }`, validated by one domain service, `LifecycleStateMachine`, which owns drafts, publish, unpublish, archive and published protection. Its tests are ported from the `content-ops` suite before any legacy path is removed.
|
|
41
|
-
- **One cursor format.** Cursors are opaque, versioned and bound to `from`, the `orderBy` column and direction. The three formats in use today (`s:`, `st:`, `o:`) are removed.
|
|
42
|
-
- **Admin statistics** (`readCreationStatistics`) stay a narrow optional storage capability outside Store. Store does not grow aggregates for one Admin chart.
|
|
43
|
-
- **Translations.** Mantle Web resolves a locale with two Store selects (the base rows, then the translation rows for the requested and the site default locale) and merges them; the requested locale wins, then the default. Both reads are Store selects, so scope, TTL and published-only apply to each. `JoinedEntryReader` is removed and no read path grows around Store.
|
|
44
|
-
|
|
45
|
-
> **Amendment (ADR-0034):** `conflict.opIndex` is exact: count and guard checks inside the batch name their statement.
|
|
46
|
-
|
|
47
|
-
### 2. Row ops and set ops
|
|
48
|
-
|
|
49
|
-
A write op's `where` is classified **on the caller's `where`, before any policy rewrite**, so an injected scope predicate never changes the class.
|
|
50
|
-
|
|
51
|
-
- **Row op:** the top level of `where` pins `id` to one value, alone or ANDed with further conditions (`{ id, performedAt: { gte } }`). It affects at most one row, may carry `lock`, and fires per-row lifecycle hooks. A row op that matches nothing is re-read by id: a present row with another version is `CONFLICT` with reason `lock`; otherwise reason `expect`.
|
|
52
|
-
- **Set op:** any other `where`. It fires no hooks. `mantle validate` and Store reject it on a Schema with a per-row `before_*`/`after_*` Trigger for that operation and on a Schema whose published entries are protected.
|
|
53
|
-
- `Procedure.target` is inferred with the same rule: a program with exactly one row op whose `where` pins `id` to an input field gets that target; otherwise `target` is explicit, as today.
|
|
54
|
-
|
|
55
|
-
> **Amendment (ADR-0034):** Row and set ops are classified on the compiled statement, and the class decides only `target` inference and whether writing no row is `CONFLICT`. A set op calls after hooks with its rows; Schemas with a before hook for that operation, or with `publishing` lifecycle, still refuse it.
|
|
56
|
-
|
|
57
|
-
### 3. Lifecycle hooks and atomicity
|
|
58
|
-
|
|
59
|
-
- A lifecycle Trigger targets a Procedure whose handler is a `ref`. `mantle validate` rejects an inline Store program as a hook target.
|
|
60
|
-
- **`before_*` is a read-only check.** It receives a read-only `CallerStore` (as guard Procedures do today) and no `ctx.invoke`. It allows the mutation by returning and rejects it by throwing; it cannot rewrite the mutation in 0.2.0. A rejection or failure means nothing in the batch is applied: before hooks always fail closed. Hooks for a multi-op batch run in op order, and for one op in Trigger-name order, all before the batch applies. Each sees committed data only, never a sibling op. OCC at apply time still guards the race between the check and the commit. The contract forbids external mutations in a before hook; this limits what Mantle injects, not arbitrary user code.
|
|
61
|
-
- **`after_*` runs only after a successful commit.** A rollback emits nothing, a failure never changes the committed result, and a write the hook makes is a new `write` in a new transaction. The hook receives the mutation snapshot (the row and version at commit), not the latest row.
|
|
62
|
-
- **Delivery.** `LifecycleTriggerSource.errorPolicy` is removed: before hooks always fail closed, and an after hook cannot change a committed result. After hooks are best effort, as today: they run inline or through `waitUntil`, and `ctx.cause.id` is stable so a handler can deduplicate a replay. Reliable delivery (an outbox written in the same batch, at-least-once) is deferred until a consumer needs it; it is an additive Trigger key.
|
|
63
|
-
- **Retries.** External side effects sit outside Store atomicity. A retry after `OUTCOME_UNKNOWN` reconciles through client ids (`store.id()`) and versions: a replayed insert conflicts on its id, a replayed update on its lock.
|
|
64
|
-
- **Identity and depth.** Hooks run with the originating `Caller`; deferred deliveries rehydrate it from the event record. `MAX_INVOCATION_DEPTH = 8` counts the `cause` chain across hook chains and `ctx.invoke`; exceeding it fails with `INVOCATION_DEPTH_EXCEEDED`.
|
|
65
|
-
- An entitlement check for one action belongs in that Procedure's `requires.guard`. A before hook is for rules every path must obey, Admin, import and maintenance included.
|
|
66
|
-
- The Store hands mutations to a `LifecycleDispatcher` port (`before(mutations)`, `after(events)`) that the Trigger layer implements; Store never references Procedures. It replaces `LifecycleHookingEntryRepository`, `RunLifecycleHooksUseCase` and `DeferredHookDispatcher`.
|
|
67
|
-
|
|
68
|
-
> **Amendment (ADR-0034):** An after hook is called once per statement and Trigger with `ctx.cause.rows`. Before hooks keep row ops and OCC.
|
|
69
|
-
|
|
70
|
-
### 4. Storage port
|
|
71
|
-
|
|
72
|
-
`StoreReader` grows into **`StoreExecutor`**: `maxBindings`, `select(query)` and `apply(batch)` over validated IR only. Every executor implements the whole IR and applies a batch atomically, so there are no capability flags; the one Core validator reads `maxBindings` (100 on D1) and removes the duplicated `NATIVE_TYPES`, depth and node checks. `ViewQueryExecutor` shrinks to native SQL Views, the remaining escape hatch.
|
|
73
|
-
|
|
74
|
-
- `SqliteStoreExecutor` serves D1, Bun and libSQL, so libSQL gains writes.
|
|
75
|
-
- `MemoryStoreExecutor` is the reference implementation, the test fake (replacing `test/fakes/in-memory-store.ts`) and the base of the IndexedDB adapter, which keeps its own persistence and concurrency tests.
|
|
76
|
-
- `@aotter/mantle/testing` exports one conformance suite that runs against every executor.
|
|
77
|
-
|
|
78
|
-
The rewrite is built in `next/`, a private package beside the shipped ones (see `next/README.md`), and replaces them at the end.
|
|
79
|
-
|
|
80
|
-
> **Amendment (ADR-0034):** `SqliteStoreExecutor` is the only executor; `MemoryStoreExecutor` is removed, and so is `ViewQueryExecutor`, since every View compiles to IR. Conformance runs on local D1 inside workerd.
|
|
81
|
-
|
|
82
|
-
### 5. Grammar is the IR
|
|
83
|
-
|
|
84
|
-
`API_VERSION` becomes `cms.mantle.aotter.net/v2`, and `RUNTIME_PLAN_VERSION` becomes 6. A v1 manifest fails with the existing apiVersion diagnostic, whose suggestion names `mantle-update`. There is no legacy lowering layer.
|
|
85
|
-
|
|
86
|
-
- **Procedure handler** is `{ ref: <name> }` or `{ store: [<write ops>] }`. `kind`, `builtin`, `op`, `match` and `BUILTIN_OPS` are removed. Views read; Procedures write, so an inline program holds write ops only. Its output is `{ results }`, the `store.write` results in op order; `mantle validate` checks the declared `output` schema accepts that shape.
|
|
87
|
-
- **View** is `spec.select` or `spec.sql`. The top-level `from`/`filter`/`fields`/`orderBy`/`limit`, the Filter AST, `$param`, `{"$ctx.user": "id"}` and `VIEW_PARAMS_RESERVED` are removed. `spec.params` is renamed `spec.input`, matching the `$input` reference.
|
|
88
|
-
- **Value references** are one set everywhere: `$input.<path>`, `$ctx.user.id`, `$now` and `{ $literal: <value> }`.
|
|
89
|
-
- **Pagination.** REST, MCP and Admin page with `limit` and `cursor` only.
|
|
90
|
-
- Staff View `uiSchema.searchFields` and `filterFields` compile to `like` and `eq` conditions.
|
|
91
|
-
- A native SQL View may not target a scoped Schema (`VIEW_SQL_SCOPED_SCHEMA`); `VIEW_TTL_NATIVE_UNSAFE` stays.
|
|
92
|
-
- **Schedule Triggers** take a five-field POSIX cron in UTC (weekday 0 = Sunday). The plan no longer carries a required host. A service that wires schedules passes `schedules: true` to `createMantle`, and boot fails for any enabled schedule without it. `toCloudflareCron` in `@aotter/mantle/cloudflare` translates an expression for Wrangler.
|
|
93
|
-
- **Webhooks.** An HTTP Trigger does not receive the raw request body in 0.2.0. The service owns its HTTP entry (decision 6), so it verifies a signature there and calls `runtime.invokeProcedure`. A raw-body Trigger key is additive and can come later.
|
|
94
|
-
|
|
95
|
-
> **Amendment (ADR-0034):** The grammar is SQL and the plan is the IR. A View is `spec.sql`, one `SELECT`, and an inline Procedure is `handler: { sql }`; `spec.select`, `{ store }` and the `$`-prefixed value references are replaced by `input.<name>`, `auth.uid()`, `auth.role()` and `now()`. Every View gets scope and TTL injected, so `VIEW_SQL_SCOPED_SCHEMA` and `VIEW_TTL_NATIVE_UNSAFE` are removed.
|
|
96
|
-
|
|
97
|
-
### 6. The portable unit is an application-owned service
|
|
98
|
-
|
|
99
|
-
```ts
|
|
100
|
-
interface MantleService<Env = unknown> {
|
|
101
|
-
readonly handlers: MantleHandlers<Env>;
|
|
102
|
-
fetch(request: Request, env: Env, context: MantleServiceContext): Response | Promise<Response>;
|
|
103
|
-
}
|
|
104
|
-
interface MantleServiceContext {
|
|
105
|
-
readonly runtime: MantleRuntime;
|
|
106
|
-
waitUntil(promise: Promise<unknown>): void;
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
- `env` stays opaque. HTTP is the service's only Mantle ingress; schedules, deferred hooks, MCP and REST enter through Trigger atoms and surfaces.
|
|
111
|
-
- **One host-neutral entry, no per-host adapter.** Once the service is a WinterTC fetch, hosts differ only in the storage driver and in how their native entry is spelled. `@aotter/mantle` exports one function:
|
|
112
|
-
|
|
113
|
-
```ts
|
|
114
|
-
createMantle(service, { storage: (env) => MantleStorageAdapter, schedules?: boolean }): {
|
|
115
|
-
fetch(request: Request, env: Env, ctx?: { waitUntil(p: Promise<unknown>): void }): Promise<Response>;
|
|
116
|
-
invokeSchedule(cron: string, scheduledTime: number, env: Env, ctx?): Promise<void>;
|
|
117
|
-
runDeferredHook(message: unknown, env: Env, ctx?): Promise<void>;
|
|
118
|
-
}
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
It boots the runtime lazily from `storage(env)`, passes it to `service.fetch`, and turns a schedule or a deferred-hook message into a Trigger invocation. The host's entry is one to three lines of **generated, application-owned** preset code (`export default { fetch: m.fetch, scheduled: (e, env, ctx) => m.invokeSchedule(e.cron, e.scheduledTime, env, ctx) }` on Cloudflare, `Bun.serve({ fetch: m.fetch })` on Bun), so an application adds its own native handlers next to Mantle's and Core absorbs no platform event types.
|
|
122
|
-
- `createMantleWorker`, `createBunMantle` and `createVercelMantle` are removed; today `createBunMantle` and `createVercelMantle` are 62-line copies of the same lazy boot. The adapter subpaths keep only what is platform-specific: `@aotter/mantle/cloudflare` the D1 driver, the KV and R2 bindings and `toCloudflareCron`; `@aotter/mantle/bun` the `bun:sqlite` driver; `@aotter/mantle/vercel` the libSQL driver. ChatGPT Sites uses the Cloudflare preset with the custom identity.
|
|
123
|
-
- **`--host` is removed** (amends ADR-0026). Whenever the selection needs an entry (anything beyond `spec`, which stays host-free), `mantle generate` emits the Cloudflare preset: the entry above with `scheduled` wired, D1 storage, and the KV and R2 bindings. `host-minimal-worker` and `host-local-admin-otp` are its reference examples.
|
|
124
|
-
- **Other hosts are examples and drivers, not generator options.** ChatGPT Sites is the `host-chatgpt-sites` reference: an agent adapts the Cloudflare preset from it (Sites sign-in, R2 media, custom identity). `@aotter/mantle/bun` (`bun:sqlite`) and `@aotter/mantle/vercel` (libSQL) keep their drivers, marked experimental until a maintainer runs them end to end; they get no preset and no promised example. On any host, a capability the entry does not wire (schedules, for example) is refused at boot with a diagnostic, never skipped silently, and the author's coding agent bridges it.
|
|
125
|
-
- `BootMantleRuntimeArgs.supportsScheduledTriggers` becomes the `schedules` option above.
|
|
126
|
-
- Removed: `MANTLE_RESERVED_PATH_PREFIXES`, `MantleExtensionApp`, `extend`, `extend.mount` and `getRuntime`. `mantle generate` emits the standard composition as application-owned source: `src/service.ts`, `src/handlers.ts` and the host entry.
|
|
127
|
-
|
|
128
|
-
### 7. Handlers, invocation and capabilities
|
|
129
|
-
|
|
130
|
-
- The codegen `MantleHandlers` type lists exactly the plan's refs. `mantle validate` and boot check both directions: a plan ref without a handler is `HANDLER_NOT_REGISTERED` (existing), a handler the plan does not declare is `HANDLER_NOT_DECLARED`.
|
|
131
|
-
- A handler receives only `(input, ctx)`. The serializable part is an **`Invocation`**: `{ procedure, input, caller, cause }`. Every source (HTTP, MCP, schedule, lifecycle, internal) produces one, and `runtime.invokeProcedure(invocation)` runs auth → guard → input → handler → output for all of them. Only an `Invocation` ever crosses a wire.
|
|
132
|
-
- `HandlerContext` is `{ caller, cause, env, waitUntil, store, invoke }`. `user`, `staff`, `auth`, `event` and `schedule` are removed.
|
|
133
|
-
- **`InvocationCause`** is `{ kind: "http" | "mcp" | "schedule" | "lifecycle" | "internal", id, parent? }` plus kind-specific facts: `trigger`, `cron` and `scheduledTime` for schedules; `trigger`, `hook`, `schema` and the mutation snapshot for lifecycle. `id` is stable across retries.
|
|
134
|
-
- **`ctx.invoke(procedure, input)`** is the one Procedure-to-Procedure entry. It keeps the caller, chains `cause.parent`, and re-runs the target's auth and guard. There is no `getRuntime` closure.
|
|
135
|
-
|
|
136
|
-
### 8. Mantle never owns the user or the auth
|
|
137
|
-
|
|
138
|
-
A service keeps its existing users and auth. `@aotter/mantle/auth` is one optional producer of the caller identity.
|
|
139
|
-
|
|
140
|
-
- **`Caller`** (in `@aotter/mantle`) replaces `HandlerContext.user`, `.staff` and `.auth`:
|
|
141
|
-
|
|
142
|
-
```ts
|
|
143
|
-
type Caller =
|
|
144
|
-
| { readonly kind: "anonymous" }
|
|
145
|
-
| { readonly kind: "user"; readonly subject: string; readonly issuer?: string;
|
|
146
|
-
readonly role: StaffRole | null; readonly scopes: readonly string[];
|
|
147
|
-
readonly credential: CredentialKind; readonly credentialId: string | null; readonly clientId: string | null }
|
|
148
|
-
| { readonly kind: "system"; readonly reason: string };
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
- **Subject key.** `subject` is the application subject key: opaque, stable and unique within the service across every issuer. The resolver owns that uniqueness (mantle-auth uses its user row id; a resolver over several IdPs namespaces the id). `issuer` is informational. `$ctx.user.id`, `scope.ownerId` and `authorId` store the subject key, with no foreign key into any users table. Identity is never keyed by email.
|
|
152
|
-
- **One authentication boundary.** The service's entry resolves the caller once per request with a **`CallerResolver`**: `(request) => Promise<{ caller: Caller } | { invalid: true; challenge?: string }>`. An invalid credential is answered 401 before any surface runs and is never treated as anonymous. Only "no credential presented" is anonymous. Roles are resolved inside the resolver on every request.
|
|
153
|
-
- **Predicates.** `requires.auth` evaluates against the `Caller` only; the grammar is unchanged. `ctx.user` and `ctx.auth` require a user caller, `ctx.staff` a role in the list, `ctx.auth.scope` a scope. `STAFF_ROLES` is Admin's vocabulary: a custom resolver maps its own roles onto it or leaves `role` null and uses scopes and guards.
|
|
154
|
-
- **System caller.** `systemCaller(reason)` is exported for host code only; no wire can produce one. It satisfies no `requires.auth` predicate (so schedule targets still declare none, as ADR-0027) and bypasses caller scope and nothing else: lifecycle rules and TTL visibility apply, and expired rows are visible only to `sweepExpired`. Schedules and maintenance run as the system caller.
|
|
155
|
-
- **Policy origins.** Scope comes from the caller; published-only from the surface or atom (a public View over a publishing Schema); TTL and lifecycle always apply. `runtime.store` is host-level and unscoped, `runtime.store.as(caller)` binds per request, and `ctx.store` arrives bound.
|
|
156
|
-
- **Admin facets.** `@aotter/mantle/admin` defines `AdminIdentity`, whose members are all optional: `directory` (`getUser`, `listUsers`, `listMembers`), `roles` (`setUserRole`, `inviteUser`, `revokeInvite`, `sendStaffInvitation`) and `deleteUser`. Admin hides what is absent. Display names come from `directory`, never from a Store join.
|
|
157
|
-
- **mantle-auth** implements `CallerResolver`, `AdminIdentity` and the optional OAuth server routes. Account deletion is its `deleteUser` facet, so services stop running raw SQL against auth tables; a custom provider owns deletion for its own users. The MCP surface verifies nothing: it takes `authorizationServer` (a URL) for its 401 challenge and protected-resource metadata.
|
|
158
|
-
- **Core creates no auth tables.** The twelve Better Auth `CREATE`s and their indexes are removed from `0001-init`, which keeps its id, so migrated databases are unchanged. mantle-auth already migrates its own schema through Better Auth's `getMigrations`; that becomes the only source of auth DDL, and Core stops carrying a copy. mantle-auth refuses to start when an auth table name belongs to a Schema.
|
|
159
|
-
- **No identity** (anonymous callers only, no auth package, no auth tables) works and is tested. It is an explicit choice, never the default.
|
|
160
|
-
- **Existing services.** Mantle is added to a running service; it does not replace it. The service keeps its entry, users, auth, tables, routes and SSR. Mantle adds `_mantle_*` system tables, the Schemas it declares, and the product tables of the modules it selects. Data the service wants Mantle to manage (Admin, MCP, Store) moves into a Schema, one table at a time, by the data owner's choice. #1102's consumer skill carries that path.
|
|
161
|
-
|
|
162
|
-
### 9. Surfaces are Fetch functions
|
|
163
|
-
|
|
164
|
-
A surface is `(request: Request, caller: Caller) => Promise<Response>`, created with its base path:
|
|
165
|
-
|
|
166
|
-
| Surface | Factory | Package |
|
|
167
|
-
|---|---|---|
|
|
168
|
-
| MCP | `createMcpSurface(runtime, { basePath, authorizationServer? })` | `@aotter/mantle/mcp` |
|
|
169
|
-
| Admin | `createAdminSurface(runtime, { basePath, identity?, assets })` | `@aotter/mantle/admin` |
|
|
170
|
-
| REST Views | `createRestSurface(runtime, { basePath })` | `@aotter/mantle/web` |
|
|
171
|
-
| Web | `createWebSurface(runtime, { basePath, ... })` | `@aotter/mantle/web` |
|
|
172
|
-
|
|
173
|
-
Admin UI assets honour the base path. Hono may stay inside a package; it is no longer in any public signature. Mantle Web and Admin read through Store, and `EntryReader` is removed. A typed client for custom frontends is deferred; it is additive. The `@aotter/mantle/admin-ui/kit` re-export and `rowBindings` are removed (#1140).
|
|
174
|
-
|
|
175
|
-
### 10. Cloud verifies the plan; the user owns the entry
|
|
176
|
-
|
|
177
|
-
- `semanticFingerprint` becomes SHA-256; it now crosses a trust boundary, which its `ponytail:` comment named as the upgrade point. It is the "compiled plan fingerprint" aotter/mantle-home#201 records.
|
|
178
|
-
- `createMantleRuntime` accepts `expectedFingerprint` and refuses to boot on a mismatch (`PLAN_FINGERPRINT_MISMATCH`).
|
|
179
|
-
- `runtime.bootReport()` returns `MantleBootReport`: `{ fingerprint, coreVersion }`. Handler refs need no report because boot already refuses a mismatch; schedules are in the plan.
|
|
180
|
-
- Cloud's guarantee names two kinds of fact. **Platform-verified:** the Cloud-compiled plan, the pinned Core, storage matching the plan (ADR-0033) and the fingerprint handshake. **Service-reported:** the surfaces and mounts the service chose, which Cloud confirms only by probing them in smoke. A service that never boots the runtime has no manifest scope to guarantee, and smoke shows that.
|
|
181
|
-
- The plugin's Cloud helper script (decision 13) distinguishes a handlers-only artifact (today's closed module, host protocol 2 per ADR-0031) from a service-entry artifact, which is closed except for `@aotter/mantle*` externals that Cloud supplies at the pinned Core. The artifact field is `artifactKind: "handlers" | "service"`; service entries use host protocol 3. aotter/mantle-home reserves the field now and accepts service entries after Core 0.2.0, as its own issue.
|
|
182
|
-
|
|
183
|
-
> **Amendment (ADR-0034):** The guarantee is a Cloud-validated plan. The CLI compiles; Cloud validates the IR and never parses SQL; whether the IR matches its SQL source is service-reported. Host protocol 3 uploads the plan.
|
|
184
|
-
|
|
185
|
-
### 11. Table namespace
|
|
186
|
-
|
|
187
|
-
Tables that start with `_mantle_` are system tables: Mantle's internal state (the ledger, boot, Schema registry, schedule runs). They are Mantle's alone and the service does not touch them. Every other table Mantle or a Mantle module creates is a **product table** and keeps its name, just as Better Auth's tables keep theirs: `site_config`, `media_assets` and `pending_media_uploads` from Core, and Better Auth's own tables from mantle-auth. #1156 is decided by this rule: no rename. `sites_users` leaves `RESERVED_TABLES`, since ChatGPT Sites' identity is application-owned.
|
|
188
|
-
|
|
189
|
-
A product table that already exists without the ledger record of the Mantle migration that creates it is someone else's table: Core refuses to boot (`STORAGE_TABLE_NOT_OWNED`) instead of reading and writing it. mantle-auth applies the same rule to `user` and the other Better Auth tables.
|
|
190
|
-
|
|
191
|
-
### 12. `mantle generate` and identity
|
|
192
|
-
|
|
193
|
-
- With no `--features`, generate emits the full preset, including mantle-auth, which creates and owns its tables.
|
|
194
|
-
- `--features` stays a positive replacement list (ADR-0026). `mantle.config.json` and the CLI gain `identity: "mantle" | "custom" | "none"`, and identity is part of the positive selection: an explicit `--features` without `--identity` means `none`, and a selected feature that needs a caller identity (`admin`) then fails with the dependency diagnostic below. `custom` emits an application-owned `src/identity.ts` implementing `CallerResolver`.
|
|
195
|
-
- **Amends ADR-0026:** dependencies are no longer closed automatically. A missing dependency fails with `GENERATE_FEATURE_DEPENDENCY_MISSING`, and an omitted module is never re-added.
|
|
196
|
-
- Switching `identity` on a rerun is refused and never drops tables.
|
|
197
|
-
- Acceptance: the default works with users and auth whose tables mantle-auth owns; `custom` keeps the service's users and adds no auth tables; an explicit public service with `none` adds no auth package or tables; a valid positive selection generates, and a missing dependency is refused with a diagnostic.
|
|
198
|
-
|
|
199
|
-
### 13. Two npm packages and one plugin
|
|
200
|
-
|
|
201
|
-
Every Mantle package versions and releases together, so splitting by area buys nothing and costs a publish, a peer and a pin per package. 0.2.0 publishes two packages, split where the dependencies, the build and the audience actually differ: server and browser.
|
|
202
|
-
|
|
203
|
-
| Package | Contents |
|
|
204
|
-
|---|---|
|
|
205
|
-
| `@aotter/mantle` | Core at the root (Store, `createMantle`, `createMantleRuntime`); subpaths `/spec`, `/testing`, `/cloudflare`, `/bun`, `/vercel`, `/indexeddb`, `/auth`, `/admin`, `/mcp`, `/web`; the `mantle` CLI |
|
|
206
|
-
| `@aotter/mantle-ui` | `/controller`, `/kit` (including the sign-in card a service's own frontend can reuse), `/mcp-app`, and the prebuilt Admin SPA at `/admin` |
|
|
207
|
-
|
|
208
|
-
- Platform and heavy libraries (`better-auth`, `hono`, `@libsql/client`, the MCP SDK, React) are optional peers. A subpath that is not imported is never loaded, so Core still requires no Admin, Web, Auth or platform code; `check:boundaries` enforces this at module level instead of package level (amends ADR-0019's optional-package boundary).
|
|
209
|
-
- `@aotter/mantle` never imports `@aotter/mantle-ui`. The generated preset passes the Admin assets from `@aotter/mantle-ui/admin` to `createAdminSurface`.
|
|
210
|
-
- `@aotter/mantle-spec`, `-runtime`, `-cloudflare`, `-bun`, `-vercel`, `-indexeddb`, `-auth`, `-admin`, `-mcp` and `-web` fold into subpaths; `@aotter/mantle-admin-ui` folds into `@aotter/mantle-ui/admin`. `@aotter/mantle-host` was never published and is removed.
|
|
211
|
-
- **The plugin** (this repository's agent plugin) ships one `mantle` skill and helper scripts. Its configuration carries the Mantle Cloud MCP endpoint as an absolute URL, `https://cloud.mantle.tools/mcp`; aotter/mantle-home provides only that MCP. The helper scripts (`.mjs`) orchestrate the Cloud MCP sequence so an agent does less by hand, and keep the upload rules whose artifact bytes depend on the Core version (ADR-0031). The `mantle-host` name disappears; ADR-0031's protocol is the host protocol. Deploying anywhere else uses that host's own CLI, and the skill states that the user may always self-host: Mantle Cloud is one option, never a requirement.
|
|
212
|
-
|
|
213
|
-
> **Amendment (ADR-0034):** `/indexeddb` is removed, with no browser driver in 0.2.0. D1 test helpers live at `/cloudflare/testing`. The plugin's helper scripts compile with the project's installed `@aotter/mantle/spec` and bundle no parser.
|
|
214
|
-
|
|
215
|
-
## 2026-10-07 amendment — metadata observation belongs to its native boundary (#1356)
|
|
216
|
-
|
|
217
|
-
MCP offers optional `onObservation` at registered tool dispatch and its existing request-refusal gates. Attempt and completion share the runtime cause ID; output/input, requested unknown names, URLs and exception messages are never observation fields. Unknown and client-hidden tools are not registered invocations. An authentication-refused request or batch is a request refusal, not a set of executed tools. Invalid credentials and session-origin refusals remain owned by `withCaller`, which offers optional `onRefusal` without parsing the body or exposing credentials.
|
|
218
|
-
|
|
219
|
-
Callbacks are best-effort and platform-independent. Their synchronous exceptions and rejected promises do not change the business result or authentication challenge; delivery promises are not awaited. A host owns request lifetime, transport, source enrichment, storage, query authorization and reporting delivery failure. A pending callback can outlive the available request lifetime or be lost. Neither callback promises exactly-once capture or transactional audit. Core adds no telemetry table, provider binding, queue or global I/O promise. The existing business Store audit contract is unchanged.
|
|
220
|
-
|
|
221
|
-
## Conformance cases
|
|
222
|
-
|
|
223
|
-
The three contracts #1188 made ADR gates are accepted only with these cases, run against every `StoreExecutor` and the lifecycle layer:
|
|
224
|
-
|
|
225
|
-
1. **Atomicity and hooks.** A hook target with an inline program is rejected. A before hook has no write and no `invoke`; its rejection applies nothing in the batch. A concurrent write between a before check and the commit fails on OCC. A rollback emits no after event. An after-hook failure leaves the committed result. A replayed after event carries the same `ctx.cause.id`.
|
|
226
|
-
2. **Row-op classification.** `{ id }` and `{ id, performedAt: { gte } }` are row ops; `{ ownerId }` is a set op; a caller-scoped rewrite of `{ id }` stays a row op; `Procedure.target` inference agrees with Store in every case.
|
|
227
|
-
3. **Caller identity.** Two callers with the same upstream id from different issuers cannot read each other's scoped rows. An invalid credential is 401, never anonymous. The system caller bypasses scope but not TTL or lifecycle. A no-identity service boots with no auth package and no auth tables.
|
|
228
|
-
|
|
229
|
-
## Consequences
|
|
230
|
-
|
|
231
|
-
- **Net deletion** of about 3,200 lines: `DatabaseEntryRepository`, `LifecycleHookingEntryRepository`, `InvokeBuiltinUseCase`, `BuiltinProjector`, the content use cases and `AtomicEntryWriteUseCase`; the `EntryRepository`, `EntryReader`, `AtomicEntryWriter` and `ExpirySweeper` ports; the declarative part of `SqliteViewCompiler`; `IndexedDbEntryRepository` and `IndexedDbViewQueryExecutor`; `page`/`show`; the in-memory test fake; the twelve auth `CREATE`s in `0001-init`.
|
|
232
|
-
- **Breaking for every consumer:** grammar, the handler API, Worker composition and the pagination wire. The release ships the `mantle-update` codemod (builtin handlers to inline programs, Filter AST to `select`, `params` to `input`, `page`/`show` to `limit`/`cursor`, `extend` to the service preset) and old-to-new tables.
|
|
233
|
-
- **Main risk: lifecycle semantics.** They move into `LifecycleStateMachine` with their tests ported first.
|
|
234
|
-
- Cloud's promise changes from "Admin at /admin" to "the surfaces you declare work at the mounts you declare".
|
|
235
|
-
- A service with working users and auth keeps them. Fresh databases without mantle-auth get no auth tables; databases that have them are left alone.
|
|
236
|
-
|
|
237
|
-
## Alternatives
|
|
238
|
-
|
|
239
|
-
- **A legacy-lowering layer** that compiles builtin ops and the Filter AST into IR without a grammar change. Rejected: it keeps the code this release deletes.
|
|
240
|
-
- **A Worker-shaped artifact.** Rejected: it leaks the Worker name, the `fetch`/`scheduled`/`queue` export shape and `cloudflare:workers` into a host-agnostic contract.
|
|
241
|
-
- **One npm package per area** (today's fourteen). Rejected: they version together, so each split adds a publish, a peer and a pin without independent releases.
|
|
242
|
-
- **One adapter factory per host** (`createMantleWorker`, `createBunMantle`, `createVercelMantle`, each taking the service). Rejected: with a WinterTC service they would differ only in the storage driver and a few lines of entry spelling, which the driver package and the generated preset already carry.
|
|
243
|
-
- **A handler-host port with remote execution.** Deferred: the service already is the host. The serializable `Invocation` keeps remote execution possible.
|
|
244
|
-
- **Keeping a Mantle-owned Worker with extension seams.** Rejected: it limits custom frontends, SSR and webhooks, and duplicates Cloud-only assembly.
|
|
245
|
-
- **An identity port in Runtime, or auth tables in Core.** Rejected in #1152: Core only ever sees a resolved `Caller`.
|
|
246
|
-
- **Prefixing every Mantle-created table** (#1156). Rejected: the prefix marks system tables. Product tables follow the same rule as Better Auth's, and the ownership check in decision 11 covers the collision risk without a rename migration for live sessions and tokens.
|
|
247
|
-
- **Moving the Core auth DDL into mantle-auth as `mantle-auth:0001`** (#1152). Rejected: mantle-auth already derives it from Better Auth's own `getMigrations`, so a copy would be a second source of truth.
|
|
248
|
-
- **`errorPolicy: continue` on before hooks.** Removed: a before hook that fails open is an unchecked rule.
|
|
249
|
-
|
|
250
|
-
## How to apply
|
|
251
|
-
|
|
252
|
-
1. Land this ADR and ADR-0033, then build in this order: the three conformance contracts; Store and cross-executor conformance; cut every legacy path over and delete it; service, surfaces and identity; Cloud service-entry artifacts. Vercel and IndexedDB completion may trail.
|
|
253
|
-
2. **Keep proven host integrations as maintained examples, not Core contracts.** Core models no host's delivery workflow, but a working integration saves the next user the search. The reference examples of decision 6 are ported to the 0.2.0 contracts and rechecked when their host changes. For ChatGPT Sites that means Sites sign-in mapped to a `CallerResolver` and an `AdminIdentity` over `sites_users` (the 0.1.x `host-chatgpt-sites` example's `chatgpt-auth.ts`, whose `chatgpt:<sub>` id is already a namespaced subject key) and R2 behind the `MediaStorage` port (its `media.ts`). That example was removed with the 0.1.x packages; [Mantle on ChatGPT Sites](../handbook/cloudflare/chatgpt-sites.md) carries the 0.2.0 guide.
|
|
254
|
-
3. New code uses only the identifiers named here. A new public name needs an amendment to this ADR.
|
|
255
|
-
4. `mantle validate` diagnostics listed here are added with the grammar slice; the runtime codes with the Store and invocation slices.
|
|
256
|
-
|
|
257
|
-
## Amendments
|
|
258
|
-
|
|
259
|
-
- **2026-09-30, plan presentation metadata.** The sealed plan carries what Admin and the MCP surface show, as optional fields copied unchanged from the manifests: `PlanSchema.name` (the declared name; the map key is lower case), `title`, `description`, `uiSchema`, `localized`; `PlanView` and `PlanProcedure` gain `uiSchema` (and `title`, `description`). They change the fingerprint and nothing else: no Store, storage or policy behavior reads them. Without them `createAdminSurface` could not name a collection, and a tool would have no description.
|
|
260
|
-
- **2026-09-30, MCP tools come from Views and Procedures only.** `createMcpSurface(runtime, { basePath, surface, resourceMetadata?, apps? })` lists a tool for each Procedure bound by an `mcp` Trigger of its surface and each View of its surface; a Schema is never a tool. `store.view` checks the call's input against the View's input schema, as `invokeProcedure` does for a Procedure.
|
|
261
|
-
- **2026-09-30, site config and media.** Core's product tables are one optional runtime capability. `sqliteStorage(driver, { site })` and `d1Storage(db, { site })` take the service's `SiteDefaults`. With them, boot runs the canonical migrations and seeds or syncs `site_config`, the prepared storage returns it as `PreparedMantleStorage.site`, and the runtime carries it as `runtime.site: MantleSite`. Without them, the tables are not created and `runtime.site` is absent.
|
|
262
|
-
- `MantleSite` has `read()`, `updateSettings(SiteSettings)` and `media(storage: MediaStorage): MediaLibrary`.
|
|
263
|
-
- `MediaStorage` is the port with `createUpload`, `commitUpload` and `deleteObject`, which uses `MediaAsset`, `MediaVariant` and `MediaVariantRole`. `r2MediaStorage({ bucket, signer, endpoint, publicBase })` in `@aotter/mantle/cloudflare` implements it. `R2MediaStorageOptions` is its option type, and the host supplies the S3 signer.
|
|
264
|
-
- A `Migration` may name the product `tables` it creates. If one of those tables exists without the migration's ledger row, boot stops with `STORAGE_TABLE_NOT_OWNED`, as decision 11 says.
|
|
265
|
-
- The migration ids and DDL are 0.1.x's (`0001-init`, `0002-media-assets`, `0003-pending-media-uploads`). Ownership is proven by next's own `_mantle_migrations` ledger. Upgrading a 0.1.x database in place is a separate step that is not built yet: its legacy `_migrations` ledger is not backfilled, and its `_mantle_boot_state` has another shape.
|
|
266
|
-
- Hazard: a new migration id must not be purely numeric like `0004-…`, because 0.1.x ledgers already hold ids of that form.
|
|
267
|
-
- Uploads go to an upload-only key. Commit checks each object's type and size through the storage itself, then publishes it under a key that no upload URL reaches. A rejected group's objects are deleted.
|
|
268
|
-
- `createAdminSurface` gains `site?: { mcpEndpoints? }` and `media?: MediaStorage`. Without both `media` and `runtime.site`, every media route answers 501 `MEDIA_NOT_CONFIGURED`. Without `runtime.site`, `/site-settings` does not exist.
|
|
269
|
-
- `/site` drops the deprecated `mcpUrl` alias, and `mcpEndpoints` defaults to `null`, not `/mcp` and `/mcp/staff`. Both are deliberate: the service decides which surfaces it mounts.
|
|
270
|
-
- Per decision 11, `sites_users` leaves `RESERVED_TABLES`.
|
|
271
|
-
- **2026-09-30, staff MCP in Admin, the tool catalog, and the auth routes.**
|
|
272
|
-
- `mcpTools(plan, surface, locale?)` returns the `McpTool` list (name, title, description, inputSchema, outputSchema, annotations, `requires`, and the `kind` and `source` Procedure or View it comes from). `createMcpSurface` registers these, hides app-only tools from a client without UI support, and returns an `McpSurface`: the `Surface` plus the `tools` it registers for such a client, in its locale. It lives in `@aotter/mantle/spec` rather than `/mcp`, because `/admin` may not import `/mcp`: `check:boundaries` gives the MCP SDK one owner folder, and `/admin` reaches only `core` and `spec`.
|
|
273
|
-
- `createAdminSurface` gains `staffMcp?: McpSurface`, which the service builds with `createMcpSurface(runtime, { basePath: "{basePath}/api/mcp", surface: "staff" })`. Admin answers it at `{basePath}/api/mcp`, for any method, after Admin's own gate (session only, staff role). With it, `GET {basePath}/api/webmcp` returns `{ tools, routes }`, and bootstrap carries the same object as `webmcp` (null without it). `tools` is the projection of `staffMcp.tools` that `tools/list` returns, so locale and apps agree; nothing recomputes the catalog. `routes` maps a tool to `{basePath}/c/<target Schema>` (`entry: true`) when its Procedure declares `target`, and to `{basePath}/views/<name>` for a View. Any other tool has no route. An MCP client with a token uses a separate mount, `withCaller(resolver, createMcpSurface(runtime, { basePath: "/mcp/staff", surface: "staff", resourceMetadata }), { resourceMetadata })`, and that surface's own staff gate. `@better-auth/mcp` serves protected-resource metadata for the single `mcpResource` only, so `/mcp/staff` shares that audience and its `resourceMetadata` is the `/mcp` metadata URL (`/.well-known/oauth-protected-resource/mcp`), never a derived `/mcp/staff` one.
|
|
274
|
-
|
|
275
|
-
> **Amendment (Admin answers no MCP):** `staffMcp` and `{basePath}/api/mcp` are removed. `GET {basePath}/api/webmcp` and bootstrap's `webmcp` are always present and are `{ tools, routes }`, where `tools` is `mcpTools(plan, "staff")` in its default locale. The browser calls a tool with `POST {basePath}/api/webmcp/<tool>` and the input as the JSON body; Admin runs it as the staff surface does (the same input split, an `mcp` cause, the session caller) and answers `{ output }`. An `appOnly` tool is hidden from MCP clients only: in Admin the agent acts as the signed-in person. Staff MCP has one mount, `/mcp/staff`, which the preset mounts whenever it mounts `/mcp` and has an identity, and reports as `site.mcpEndpoints.staff`.
|
|
276
|
-
- `GET {basePath}/api/developer-console` is owner only. It returns `dataModel` (schemas, and non-internal Views with their IR as `sql: { grammar, stmts }`), `logic` (Procedures with `handler` as `{ ref }` or `{ sql }` IR, and triggers) and `operations`. `operations` holds `schedules` (`registration: "not-observed"`), `ttlPolicies` (`sweepObservation: "unavailable"`), `observationAvailability: "unavailable"` and empty `runs` and `latestRuns`: 0.2.0 has no run observation store. The 0.1 `graph` and `interfaces` projections are dropped; the console draws from the IR (ADR-0034).
|
|
277
|
-
- `GET {basePath}/api/collections/{name}/statistics` answers 404 for an unknown collection and 501 otherwise, with the wire code `STATISTICS_UNAVAILABLE` (not a `DiagnosticCode`), until a storage offers the decision 1 capability.
|
|
278
|
-
- `createAuthRoutes(auth: AuthRoutesAuth, options: AuthRoutesOptions)` (`{ resolver, connectedAppsPage? }`) in `@aotter/mantle/auth` is the service's auth entry. It returns `(request, context?) => Promise<Response | null>`, which is `null` for a path it does not own.
|
|
279
|
-
- It answers `GET {auth.basePath}/methods` itself.
|
|
280
|
-
- It hands the rest of `{auth.basePath}/*`, `/.well-known/oauth-authorization-server/*` and `/.well-known/oauth-protected-resource[/*]` to `auth.handler` without resolving a caller. Better Auth serves both metadata documents natively (`oauthProvider` and `@better-auth/mcp`), so Mantle writes none; the protected-resource document exists for the one `mcpResource`, at `/.well-known/oauth-protected-resource` and that resource's path.
|
|
281
|
-
- It runs `/oauth/consent[/data]` and `/oauth/consents[/data|/revoke]` behind `withCaller(resolver, …)`, so a cross-site session POST is refused there. Only a `session` credential may read, give or revoke a consent. The consent redirect is only what `completeOAuthConsent` returns, and one that does not parse, or is `javascript:`, `data:`, `vbscript:` or `blob:`, is 400.
|
|
282
|
-
- Admin is an optional subpath (decision 13), so `GET /oauth/consent` and `GET /oauth/consents` answer plain HTML pages. With Admin, `oauthProvider.consentPage` points at Admin's page, and `connectedAppsPage` redirects the list there. Admin's page is `/admin/oauth/consent` (amended 2026-10-04, #1325: Admin rendered consent only at `/oauth/consent`, which `createAuthRoutes` answers first, so the pointer could not reach it).
|
|
283
|
-
- **2026-09-30, `mantle generate`, the plan file and the generated module** (decisions 6, 7, 12 and 13; ADR-0033 decision 3; ADR-0034 decision 7).
|
|
284
|
-
- **The bin.** `@aotter/mantle` declares one bin, `mantle` (`src/cli/main.ts`). Its commands are `generate` (with `--check`) and the manifest commands `validate`, `introspect`, `emit-openapi` and `emit-types`. `mantle-update` is a separate bin, added with the codemod. The entry is TypeScript, so the bin runs only once the swap builds the package; until then `runGenerate` is what tests exercise.
|
|
285
|
-
- **`mantle generate [--manifests <dir>] [--features <list>] [--identity <kind>]`.**
|
|
286
|
-
- It reads every `.yaml` and `.yml` file directly in the manifest directory (default `./manifests`) and runs parse, validate and `compileLinkedPlan`.
|
|
287
|
-
- It writes `.mantle/generated/plan.json` and `.mantle/generated/mantle.ts`, and writes `mantle.config.json` at the project root when the selection changes. It refuses (exit 2) to write through a symlinked `.mantle` or `.mantle/generated`.
|
|
288
|
-
- It reads only files, so a directory named `x.yaml` is not a manifest, and it names the manifest directory as it was given, never by its absolute path.
|
|
289
|
-
- It also writes the service preset once (amendment "the service preset" below); an application that already has `src/service.ts` keeps its own entry.
|
|
290
|
-
- **`plan.json`** is the one copy of the plan: `{ "sourceHash": <hex>, "plan": <RuntimePlan> }` as `compileLinkedPlan` returns it, with two-space indentation and a trailing newline. Its key order is deterministic, so identical input gives identical bytes, and it is not sorted: a JSON Schema's `properties` keep the order Admin and MCP show.
|
|
291
|
-
- `sourceHash` is ADR-0034 decision 7's source hash. It is the SHA-256 of the JSON array `[[name, text], …]` of the manifest files, sorted by file name, so the project's location never enters it. A text loses a leading BOM and has CRLF read as LF first, so a Windows checkout is the same source; `--check` compares generated files the same way. Host protocol 3 uploads this file.
|
|
292
|
-
- The hash sits beside the plan, not in it, so it is **not part of the fingerprint**. Reformatting a manifest changes `sourceHash`, but not the fingerprint Cloud and boot compare.
|
|
293
|
-
- **`mantle.ts`** imports `./plan.json` (`with { type: "json" }`) and exports:
|
|
294
|
-
- `plan` (the `RuntimePlan`, for `createMantle`) and `sourceHash`;
|
|
295
|
-
- the `emit-types` namespace `Mantle`;
|
|
296
|
-
- `Schemas`, `Views`, `ViewOptions` (`limit`, `cursor` and the View's `input`, required when the View requires any), and `Store` and `CallerStore` typed over them. `select` has one overload per Schema, and an insert's `values` or an update's `set` never names the scope field, which Store fills (ADR-0034 decision 8), or a native column. On a `publishing` Schema an insert is a draft, so its `values` are all optional, and an update's `set` may instead be `{ status: ContentState }` alone;
|
|
297
|
-
- `Handler<I, O, Env>`, whose `ctx.store` is that `CallerStore`, and `MantleHandlers<Env>`. `MantleHandlers` has exactly the plan's refs, so a missing or an extra handler is a `tsc` error; a plan without refs takes no handler. It stays assignable to Core's `MantleService.handlers` without a cast. Known limit: an extra ref is a `tsc` error only in an object literal typed as `MantleHandlers`; boot's `HANDLER_NOT_DECLARED` catches the rest.
|
|
298
|
-
|
|
299
|
-
`mantle.ts` imports only types, from `@aotter/mantle` and `@aotter/mantle/spec`.
|
|
300
|
-
- **`ViewRow_<name>`.**
|
|
301
|
-
- `viewOutputs(view, schemas)` in `@aotter/mantle/spec` reads a compiled `SELECT`'s outputs: an output's `AS` name, else its column's name, and `*` as the Schema's declared fields without the scope field. `compilePlan` records the outputs that read a Schema field unchanged as `PlanView.columns` (`{ <output>: { schema, field } }`, which changes the fingerprint).
|
|
302
|
-
- **`store.view` decodes those columns as `store.select` does** (booleans, JSON, timestamps, dates, numerics) and names an output that is the field's own name as declared (`e.startsAt AS startsAt` comes back as `startsAt`); another alias keeps its own name. An expression (`e.title || '!'`) keeps the storage encoding. Before this, every View row came back in the storage encoding with lower-case keys.
|
|
303
|
-
- The row type gives such a column its field's type, as `NonNullable<Entry_<schema>[<field>]> | null`, and any other output `unknown`. The row is `unknown` when an output has no name, or a `*` reads a subquery or `json_each`.
|
|
304
|
-
- `emitTypesFromManifests` gains the option `rows` (View name to row type), which the generator passes. `mantle emit-types` has no plan, so its rows stay `unknown`.
|
|
305
|
-
- **`mantle.config.json` v2** is `{ "version": 2, "identity": "mantle" | "custom" | "none", "features": [...] }`. `host` and `output` are removed. `features` is a subset of `mcp`, `admin`, `web`, in that order.
|
|
306
|
-
- `mcp` needs `@modelcontextprotocol/server` and `@modelcontextprotocol/ext-apps`.
|
|
307
|
-
- `admin` needs `@aotter/mantle-ui`, for the Admin SPA, and an identity other than `none`.
|
|
308
|
-
- `web` is `@aotter/mantle/web`. It needs no peer and today serves `createRestSurface`; `createWebSurface` is not ported yet.
|
|
309
|
-
- Identity `mantle` needs `better-auth`, `@better-auth/oauth-provider`, `@better-auth/mcp` and `@better-auth/cimd`, the packages `@aotter/mantle/auth` imports. Every selection needs `@aotter/mantle`.
|
|
310
|
-
|
|
311
|
-
Without a config or flags, the selection is identity `mantle` and every feature. An explicit `--features` without `--identity` means `none` (decision 12). A rerun keeps the saved identity, and asking for another one is refused (exit 2), never a table drop. A changed `--features` rewrites the config. The config is rewritten only when the selection (identity or features) changes, and keeps any other key it holds; a config with the same selection in another layout is not stale. A config that is not JSON, or not a JSON object, fails with exit 2 and names the file.
|
|
312
|
-
- **`GENERATE_FEATURE_DEPENDENCY_MISSING`** (validate phase) is raised for:
|
|
313
|
-
- a selected feature or identity whose package is not installed, found as `node_modules/<name>/package.json` from the project root upward (under Yarn PnP, by Node's resolution; elsewhere Node's resolution is not used, since it also follows `NODE_PATH`, which a bundler does not);
|
|
314
|
-
- `admin` with identity `none`.
|
|
315
|
-
|
|
316
|
-
The message carries the exact install command, chosen by the lockfile in the nearest directory that has one: `pnpm add`, `yarn add`, `bun add` or `npm install`. Generate fails before it writes anything. It never installs, never edits `package.json`, and never adds a feature back (amends ADR-0026).
|
|
317
|
-
- **`SCHEMA_NAME_CASE_COLLISION` and `FIELD_NAME_CASE_COLLISION`** (validate phase, in the graph validator, so `compilePlan` raises them too): two Schemas, or two fields of one Schema, whose names differ only by case. SQL resolves identifiers case-insensitively and the plan keys both by the lower-case name, so they would otherwise become one table or one column.
|
|
318
|
-
- **0.1.x input.** A `cms.mantle.aotter.net/v1` manifest fails with the parser's apiVersion diagnostic. A `mantle.config.json` with `version: 1` or a `host` fails with exit 2. Both messages name `mantle-update`.
|
|
319
|
-
- **`mantle generate --check [--database <file>]`** writes nothing. It exits 1 when `plan.json`, `mantle.ts` or `mantle.config.json` differs from what generate would write, or a dependency is missing.
|
|
320
|
-
- With `--database`, it also reads that database. The file is a SQLite file, such as Wrangler's local D1 under `.wrangler/state/v3/d1/`, opened read-only with `node:sqlite`, verified on Node 22.14 (it prints Node's experimental warning there). Node 22's `node:sqlite` binds only anonymous `?`, so the CLI's driver rewrites Core's numbered `?N` in order.
|
|
321
|
-
- The result comes from `planStorageChanges(driver, schemas, { fingerprint })` in Core's storage module, which shares convergence's one `diff` and applies nothing, and returns `{ skipped, sql, blocked, undeclared }`. `skipped` is a database that already booted this fingerprint, where boot applies nothing, and the check says so. Otherwise it prints the SQL: the system DDL (`IF NOT EXISTS`, only where Mantle never booted) and the Schema changes, with binds inlined as literals, so the SQL replays; or "nothing to do". The fingerprint and time zone rows are left to boot.
|
|
322
|
-
- Undeclared differences are printed as comments. A blocked difference is printed instead of any SQL and fails the check with exit 1. A database that cannot be read (missing, corrupt, locked, a directory) fails with exit 2 as `--database <file>: <reason>`.
|
|
323
|
-
- Without `--database`, no database is read. ADR-0034 decision 6's "`node:sqlite` is not used" concerns the storage test line, and still holds.
|
|
324
|
-
- **2026-09-30, the service preset, `toCloudflareCron` and the schedule gate** (decisions 5, 6, 8, 9 and 12).
|
|
325
|
-
- **Written once, then the application's.** `mantle generate` (not `--check`) writes each preset file that does not exist and never overwrites one; `--check` neither reads nor reports them. When `src/service.ts` already exists the application owns its composition and no preset file is written. `wrangler.jsonc` is skipped when any `wrangler.jsonc`, `wrangler.json` or `wrangler.toml` exists, and an existing `.gitignore` is left alone. `.mantle/generated` is not ignored: `--check` compares it, so it is committed.
|
|
326
|
-
- **The files.**
|
|
327
|
-
- `src/service.ts` exports `Env` and `mantle`, the `createMantle` result over the generated `plan`, `handlers`, `d1Storage(env.DB)` and `schedules: true`. Its `MantleService.fetch` mounts, in this order: the auth routes (identity `mantle`), Admin at `/admin` (feature `admin`), the public MCP surface at `/mcp` (feature `mcp`), and the REST surface at `/api`, which answers everything else. REST is always mounted; feature `web` selects nothing more until `createWebSurface` is ported (this replaces "`web` … serves `createRestSurface`" above). With `admin` and `mcp`, Admin also gets `staffMcp` at `/admin/api/mcp` and `site.mcpEndpoints` `{ public: "/mcp", staff: null }`.
|
|
328
|
-
|
|
329
|
-
> **Amendment (Admin answers no MCP):** with `mcp` and an identity, the preset mounts the staff surface at `/mcp/staff` (before `/mcp`, with the `/mcp` `resourceMetadata`) and Admin's `site.mcpEndpoints` is `{ public: "/mcp", staff: "/mcp/staff" }`; Admin gets no `staffMcp`.
|
|
330
|
-
- Identity `mantle`: `createMantleAuth` over `env.DB` (Better Auth's D1 dialect and `d1Driver`), email OTP through `ConsoleEmailSender`, `bootstrapOwner` by `ADMIN_EMAIL`, `ipAddressHeaders: ["cf-connecting-ip"]`, and an OAuth provider whose `mcpResource` is `{PUBLIC_ORIGIN}/mcp`; then `createCallerResolver` (with `jwtBearer` for that audience), `withCaller` around every surface, `createAuthRoutes`, and an `AdminIdentity` whose facets are the auth's own methods. Without `BETTER_AUTH_SECRET` and `ADMIN_EMAIL`, or when `PUBLIC_ORIGIN` is unset or is not a loopback `http:` origin (an unset value is never local: the request's `Origin` header is not evidence, so a forged loopback `Origin` prints no code), it uses `createSetupIncompleteAuth` instead, because codes printed to the log are for local development only; a deployed service replaces the sender and the method.
|
|
331
|
-
- Identity `custom`: `src/identity.ts` exports `resolveCaller: CallerResolver`, which throws until the application implements it, so a request fails loudly instead of running as anonymous. Admin gets no `identity`, so it hides the user facets.
|
|
332
|
-
- Identity `none`: every surface runs with the anonymous caller; no auth package is imported and no auth table is created.
|
|
333
|
-
- `src/handlers.ts` exports `handlers: MantleHandlers` with one stub per plan ref, each throwing `not implemented: <ref>`.
|
|
334
|
-
- `src/index.ts` is the Cloudflare entry: `fetch` and `scheduled`, no `queue` (no Core path produces a deferred-hook message). `scheduled` maps `controller.cron`, which Cloudflare spells as `wrangler.jsonc` does, back to the plan's POSIX expression through `toCloudflareCron` over `plan.triggers`, computed at module load from the enabled schedule Triggers, and calls `mantle.invokeSchedule` for each POSIX spelling that maps to it, so Triggers whose expressions differ but share one Cloudflare cron all run, and every failure is reported together in an `AggregateError`. A cron no Trigger maps to throws. Both handlers pass `{ waitUntil }` imported from `cloudflare:workers`, which is not bound to one request, so a handler's `ctx.waitUntil` never lands on another request's finished context (the open item "waitUntil captured per last request"). `env` is the isolate's, which Workers keeps the same for every request.
|
|
335
|
-
- `wrangler.jsonc`: `main: "src/index.ts"`, `compatibility_date: "2026-09-01"`, `compatibility_flags: ["nodejs_compat"]`, the D1 binding `DB`, and `triggers.crons` with `toCloudflareCron` of each enabled schedule Trigger, deduplicated. No R2 binding: media purposes live in the service's `SiteDefaults`, not in the plan, so generate cannot see them; an application that adds media adds the binding.
|
|
336
|
-
- `tsconfig.json` (`module: "ESNext"`, `moduleResolution: "Bundler"`, `resolveJsonModule`, `strict`, `types: ["@cloudflare/workers-types", "node"]`, since `nodejs_compat` serves the `node:` modules `/auth` imports), `.dev.vars.example` (identity `mantle`: `BETTER_AUTH_SECRET`, `PUBLIC_ORIGIN`, `ADMIN_EMAIL`) and `.gitignore` (`node_modules/`, `.wrangler/`, `.dev.vars`). The project installs `wrangler`, `@cloudflare/workers-types` and `@types/node` itself; generate does not check them.
|
|
337
|
-
- Admin gets no `assets` yet: its API answers and its SPA routes are 404 until `@aotter/mantle-ui/admin` exists (decision 13), which the preset will then pass.
|
|
338
|
-
- **`toCloudflareCron(cron: string): string`** in `@aotter/mantle/cloudflare`. Cloudflare numbers weekdays 1 (Sunday) to 7 (Saturday); POSIX 0 to 6. It adds one to every explicit weekday number (a single value, a list member, both ends of a range; a step is kept, so `1-5/2` becomes `2-6/2`), leaves `*` and weekday names (`SUN`–`SAT`) as written, and leaves the other four fields unchanged. It throws an `Error` naming the expression for what it cannot map faithfully: not five fields, a token that is not a number, name, `*`, range or step (`?`, `L`, `W`, `#`), weekday `7`, a weekday number past 6, a number with a leading zero (`01` and `1` would name one Cloudflare cron for two spellings), a value outside its field's range, a range that runs backwards (`5-1`), a name with a step (`MON/2`), a step below 1, and a day of month other than `*` together with a weekday other than `*`, where POSIX runs on either and Cloudflare's rule is not documented to match.
|
|
339
|
-
- Since the grammar has no rule across cron fields, generate (and `--check`) runs `toCloudflareCron` on every enabled schedule Trigger first, and a refusal fails with exit 1 as `Trigger <name>: <message>` before anything is written. Once `src/service.ts` exists the application owns it and `wrangler.jsonc`, so a plain `generate` only compares: it prints a `warning:` when `triggers.crons` differs from the plan's schedule Triggers or the selection changed, and writes neither file. `src/service.ts` is written last, so a preset write that failed (exit 2, `cannot write <path>`) is finished by the rerun.
|
|
340
|
-
- **The schedule cause.** A schedule's `cause.id` stays `<trigger>:<scheduledTime>`, so a replay of the same (Trigger, `scheduledTime`) carries the same id and a handler can deduplicate it.
|
|
341
|
-
- **`withCaller` moves to `@aotter/mantle`** (Core), with `WithCallerOptions`: it needs only a `CallerResolver` and a `Surface`, and `@aotter/mantle/auth` imports Better Auth, so a `custom` service that imported it from there bundled Better Auth. `/auth` no longer exports it.
|
|
342
|
-
- **The Worker never bundles the SQL compiler.** `core`, `cloudflare`, `web`, `auth`, `admin` and `mcp` import `spec/kernel` and `spec/domain`, never the `spec` barrel, whose `infrastructure/sql` re-export pulls `libpg-query` into a bundle even behind a dynamic import. `@aotter/mantle/spec` still exports `compilePlan`. A test bundles the generated entry (identity `mantle`, every feature) with esbuild and asserts no `libpg-query` input.
|
|
343
|
-
- **The schedule gate** replaces `check:schedule-cf` at the swap PR (until then the root `check` still runs the old script): it boots a generated preset under Wrangler's `unstable_startWorker`, fires `/cdn-cgi/local/scheduled` with the `wrangler.jsonc` spelling of the cron, and asserts the Trigger's Procedure ran once with `cause.kind: "schedule"`, and that a replay with the same `scheduledTime` carries the same `cause.id`.
|
|
344
|
-
- **2026-09-30, staff management goes through Better Auth's admin API** (decision 8). `createMantleAuth` already installs Better Auth's `admin` plugin with the staff roles as `adminRoles` and their access-control statements, yet `listUsers`, `setUserRole` and `inviteUser` wrote its tables in SQL, because the facet gave them no request to act as. They now take the signed-in owner's `Request` first, and `createMantleAuth` forwards its headers to `auth.api.listUsers` (`filterField: "role"`, `filterOperator: "in"`), `auth.api.setRole` and `auth.api.createUser`, so Better Auth authorizes the call with its own role statements, and its session store sees the change without a second path for a session cache:
|
|
345
|
-
- `AdminIdentity.directory.listUsers(request)`, `AdminIdentity.roles.setUserRole(request, userId, role)` and `AdminIdentity.roles.inviteUser(request, email, role)`; `MantleAuth` has the same signatures. Admin passes the request it is serving. `listUsers` still returns every staff user: Better Auth answers 100 unless given a limit, so a longer list is read again with its total as the limit.
|
|
346
|
-
- `setUserRole(request, userId, null)` stores Better Auth's default role `user`, which is not a staff role, instead of `NULL`; both read as "not staff" everywhere (`CallerResolver`, `listMembers`).
|
|
347
|
-
- Unchanged, because Better Auth has no call for them: `listMembers` (cursor paging that excludes every staff role; `listUsers` pages by offset and filters on one field), `getUser`, `listLinkedAccounts` and `unlinkAccount` for another user (`listUserAccounts` and `unlinkAccount` act on the session's own user), `revokeInvite` (one `DELETE` whose guard, no verified email and no linked account, holds in the same statement), and the OAuth consent calls. `deleteUser` stays headerless for a service's own code and always uses Better Auth's `internalAdapter.deleteUser`, which also clears cached sessions, instead of SQL when no session cache is configured.
|
|
348
|
-
- **2026-09-30, `@aotter/mantle/auth` exports its contract only.** Its values are `createMantleAuth`, `createSetupIncompleteAuth`, `createAuthRoutes`, what `callerResolver` exports, `ConsoleEmailSender` and `appleClientSecret`, with their types. The option builders (`buildGenericOAuthProviders`, `buildOAuthProviderOptions`, `buildSocialProviders`, `buildTrustedOriginsFor`, `guardGithubLoginProfile`, `hasEmailAuthSurface`, `hashEmailOtp`, `normalizeAuthBasePath`, `normalizeAuthResponseCookies`, `pickLocale`, `resolveClientIpHeaders`, `shouldPromoteToOwner`, `validateBootstrap`), the token helpers (`getProviderAccessTokenForRequest`, `mapRegisteredOAuthClient`, `verifyOAuthJwt`, `verifyOAuthJwtWithLocalJwks`), `STAFF_ROLES`, `STAFF_ROLE_SET` and the member cursors (`decodeMemberCursor`, `encodeMemberCursor`) were exported only for tests or for Admin, which has its own; `MantleAuth.getProviderAccessToken` still serves a service's own code. `isSetupIncompleteAuth` had no caller and is deleted.
|
|
349
|
-
- **2026-09-30, the `mantle` bin is one command, `generate`.** `validate`, `introspect`, `emit-openapi` and `emit-types` are removed: `generate` validates and compiles (`--check` is the gate that writes nothing and exits 1), `plan.json` is what `introspect` printed, and the generated `mantle.ts` holds every type `emit-types` wrote. `emit-openapi` had no caller. Its handler-source grep (`HANDLER_NOT_REGISTERED` as a warning) goes too: the typed `mantle.ts` makes a missing or extra handler a type error. `@aotter/mantle/spec` no longer exports `IntrospectManifestsUseCase`, `EmitOpenapiUseCase`, `EmitTypesUseCase` or their DTOs (`IntrospectManifestsRequest`, `IntrospectManifestsResponse`, `IntrospectedProcedure`, `IntrospectedSchema`, `IntrospectedTrigger`, `IntrospectedView`, `EmitOpenapiRequest`, `EmitOpenapiResponse`, `EmitTypesRequest`, `EmitTypesResponse`); `emitTypesFromManifests` stays, and `ValidateManifestsRequest` loses `handlerSource`.
|
|
350
|
-
- **2026-09-30, no `mantle-update` codemod; an upgrade guide for agents instead** (Consequences, and the amendment "`mantle generate`"). The codemod and its bin are not built. A 0.1.x project moves by hand, usually with a coding agent, following `docs/upgrade-0.1-to-0.2.md`, which ships in the package's `docs/`. The rewrites the codemod was to make (builtin handlers to SQL, the Filter AST and `params` to a View's SQL and `input`, `page`/`show` to `limit`/`cursor`, `ctx.event.entry` to a loop over `ctx.cause.rows`, Cloudflare cron to POSIX, `extend` to the service preset) are rows of that guide. A v1 manifest and a v1 `mantle.config.json` still fail as before; their messages name the guide instead of `mantle-update`.
|
|
351
|
-
- **2026-09-30, `x-mantle-bind` is refused** (ADR-0034 decision 8). In 0.1.x the keyword stamped a field on every write. 0.2.0 parsed and validated it, but no write path read it, so a field an author believed stamped took whatever the caller sent. The keyword is now refused on any Schema property, with a message naming the replacements: `Schema.spec.scope` for the caller's own field, and `auth.uid()` or `now()` in the Procedure's SQL for the rest. `@aotter/mantle/spec` no longer exports `MANTLE_BIND_VALUES` or `MantleBindValue`, and the diagnostic code `BIND_VALUE_NOT_IN_ENUM` is removed; `MANTLE_BIND_KEYWORD` stays, naming what is refused.
|
|
352
|
-
|
|
353
|
-
- **2026-10-01, the Admin console is `@aotter/mantle-ui/admin`, and Admin's wire reads the 0.2 plan** (decision 13, the swap's last step).
|
|
354
|
-
- **Package.** `@aotter/mantle-admin-ui` is removed. Its SPA builds into `@aotter/mantle-ui`'s `dist/admin/` (export `./admin/index.html`), with base `/admin/` instead of 0.1's `/_mantle/admin/`. The default site icons follow it to `/admin/favicon.*`. Removed with the package: its `/kit`, `kit.css` and `tokens.css` re-exports (the kit is `@aotter/mantle-ui/kit`), the shadcn `registry/auth-page.json` item, and the `systemTokensCss` export. 0.2.0 publishes two packages.
|
|
355
|
-
- **Serving.** With the admin feature, the Cloudflare preset binds `node_modules/@aotter/mantle-ui/dist/admin` as the Worker's static assets (`ASSETS`, `run_worker_first`, `html_handling: none`) and passes `createAdminSurface` an `assets` that fetches from it. Admin answers every `/admin` path; nothing is served at the files' bare paths.
|
|
356
|
-
- **Developer console.** `GET {base}/api/developer-console` is the snapshot the console reads: the data model, the logic with each audience, the HTTP and MCP interfaces, and a graph whose relations come from the IR (a View's sources, a Procedure's writes) and the plan. A View's query and an inline handler are `{ kind: "sql", statement }`, the SQL as authored; the IR stays on the server. The plan carries that text as `PlanView.source` and an inline handler's `source`, presentation metadata like `title`.
|
|
357
|
-
- **Views.** `/views-manifest` lists each staff View with `input`, `list.columns` and `columns`: each output that reads a Schema field unchanged, so Admin labels and formats it as that field. It also carries `list.searchFields` and `list.filterFields` (decision 5, below). The console pages Views by cursor only.
|
|
358
|
-
- **Settings.** `/site-settings` without the site tables answers 501 `SITE_NOT_CONFIGURED` (a new diagnostic code) instead of a bare 404.
|
|
359
|
-
- **Store.** A `null` for a field the Schema does not require clears it: it is stored as NULL, which is how Store reads an unset field, so a read-modify-write round trip validates. A `null` for a required field is still refused.
|
|
360
|
-
- **Search and filters (decision 5).** A staff View's `uiSchema.list.searchFields` and `filterFields` compile to conditions on its outputs, as decision 5 says; this replaces an earlier draft of this amendment that removed them, which was never decided. `store.view(name, { search, filters })` (`StoreViewOptions`) adds, around the View's own query and inside its paging, one `LIKE` per `searchFields` output, ORed, with the text's `%`, `_` and `\` escaped, and one `=` per `filters` entry, its value encoded as the output's Schema field. Store refuses a `search` on a View without `searchFields` and a filter on an output `filterFields` does not name (`INPUT_VALIDATION_FAILED`), so a request never chooses a column. Admin's `/views/{name}` and `/export` read `search` and `filter.<output>`, coercing a filter to the output's field type, and the console's search box and filters send them. `compilePlan` refuses a name the View's `SELECT` does not output (`VIEW_UI_INVALID`). These two keys are the one part of `uiSchema` that Store reads; the rest stays presentation only.
|
|
361
|
-
- **Not in 0.2.0 yet.** The ADR-0029 interaction tools (`read_entry`, `preview_entry`, View row actions) are not on `createMcpSurface`. The console keeps its optional row-action code, and the surface sends no row actions.
|
|
362
|
-
|
|
363
|
-
> **Amendment (MCP App catalog):** row actions reach an MCP App through the catalog `planApp` embeds in the App's HTML (ADR-0029 amendment), not through results; `read_entry` and `preview_entry` stay out, and a locked action reviews the row as listed.
|
|
364
|
-
|
|
365
|
-
## Implementation status
|
|
366
|
-
|
|
367
|
-
Proposed. Nothing in decisions 1–13 is implemented beyond the ADR-0030 slices already on `develop`.
|
|
368
|
-
|
|
369
|
-
## 2026-10-08 amendment — optional staff media MCP
|
|
370
|
-
|
|
371
|
-
Issue #1384 restores the pre-consolidation media lifecycle without adding
|
|
372
|
-
Schema CRUD or a new Runtime path. `createMcpSurface` may receive `media:
|
|
373
|
-
MediaStorage`; only a staff surface with `runtime.site` advertises the native
|
|
374
|
-
media policy/create/commit/list/get/update/delete tools. They delegate to the
|
|
375
|
-
same `runtime.site.media(media)` library as Admin and use its editor/owner
|
|
376
|
-
permission, purpose/type/size validation, expiry and object verification.
|
|
377
|
-
The surface retains its shared credential scope floor and invocation
|
|
378
|
-
observations; a collision with a manifest Procedure/View fails at assembly.
|
|
379
|
-
Media bytes remain direct PUT capabilities. The deliberately removed base64
|
|
380
|
-
variant-upload tool is not restored. No grammar, portable Runtime execution,
|
|
381
|
-
storage schema or provider ownership changes. Application-owned/generated
|
|
382
|
-
service files pass their chosen adapter to both Admin and staff MCP; the
|
|
383
|
-
preset cannot invent object-storage credentials. Admin WebMCP continues to
|
|
384
|
-
list manifest tools; its native media operations remain REST-backed.
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
# ADR-0033: Schema storage converges to the plan; Mantle verifies, the author changes
|
|
2
|
-
|
|
3
|
-
**Status:** Accepted for 0.2.0 (#1188). Amends ADR-0024; replaces the reviewed-artifact workflow of #1080 and #1086. Amended by [ADR-0034](0034-store-is-authored-as-sql.md) and [ADR-0035](0035-sql-dialects.md).
|
|
4
|
-
|
|
5
|
-
**Date:** 2026-09-27
|
|
6
|
-
|
|
7
|
-
**Related:** ADR-0007, ADR-0024, ADR-0025, ADR-0032, #1011, #1080, #1086, #1150, #1192
|
|
8
|
-
|
|
9
|
-
## Context
|
|
10
|
-
|
|
11
|
-
Schema tables (ADR-0024) evolve through an operation history:
|
|
12
|
-
|
|
13
|
-
- every created table, added column and index is a ledger id (`schema-table-v2:table:…`, `…:column:…`, `…:index:…`) in `_mantle_migrations`;
|
|
14
|
-
- `_mantle_schema_tables` stores the projection Mantle *believes* each table has, and boot compares the plan against that record (`isAdditiveSchemaTableChange`), not against the database;
|
|
15
|
-
- managed hosts (ChatGPT Sites, Cloud) get append-only `drizzle/*.sql` files from `buildSqliteMigrationArtifact` (#1086), and a unique-index change needs a reviewed artifact (#1080);
|
|
16
|
-
- anything else destructive is refused, and ADR-0024 tells operators to rebuild the database.
|
|
17
|
-
|
|
18
|
-
This has three costs. Authors and their agents maintain migration files they did not write. The record can drift from the real database, and Mantle cannot see it: an index the author stopped declaring stays in place forever (#1011). And every change Mantle cannot classify has no supported path.
|
|
19
|
-
|
|
20
|
-
Better Auth's `getMigrations`, which mantle-auth already runs for its own tables, takes the other approach: it introspects the database, diffs it against the configured schema, applies additions only, never drops or alters, and stops with an explanation when it cannot proceed (`UnsafeMigrationError`, a conflicting index). ADR-0007 makes the author's agent the primary author; the change Mantle cannot make safely is exactly the change that agent should make.
|
|
21
|
-
|
|
22
|
-
## Decision
|
|
23
|
-
|
|
24
|
-
### 1. The database is the state; the plan is the target
|
|
25
|
-
|
|
26
|
-
For each Schema, the target is the plan's table: native columns, one column per scalar field, and the declared indexes. The actual state is read from the database (`sqlite_schema`, `PRAGMA table_info`, `PRAGMA index_list`, `PRAGMA index_info`), never from a Mantle record of past operations.
|
|
27
|
-
|
|
28
|
-
The diff classifies every difference:
|
|
29
|
-
|
|
30
|
-
| Class | Differences | Mantle |
|
|
31
|
-
|---|---|---|
|
|
32
|
-
| **Safe** | a missing Schema table; a missing field column (Schema columns are nullable, ADR-0030); a missing non-unique index; a missing unique index whose creation succeeds | applies it |
|
|
33
|
-
| **Blocked** | a unique index that fails on existing data; a column whose type affinity differs; an index with a declared name but other columns or uniqueness; an undeclared **unique** index (it still constrains writes); a missing native column | refuses, with `STORAGE_CHANGE_BLOCKED` |
|
|
34
|
-
| **Undeclared** | a column or non-unique index that exists but is not in the plan (a removed field, an abandoned index) | reports a warning (`STORAGE_UNDECLARED_COLUMN`, `STORAGE_UNDECLARED_INDEX`); never drops |
|
|
35
|
-
|
|
36
|
-
A renamed field is an undeclared old column plus a missing new one; the author copies the data. A unique index is not tested for duplicates in advance: `CREATE UNIQUE INDEX` is attempted, and a constraint failure turns it into a blocked change with the failing index named.
|
|
37
|
-
|
|
38
|
-
### 2. Mantle verifies; the author changes
|
|
39
|
-
|
|
40
|
-
A blocked diagnostic carries the actual state, the target and, as a hint only, SQL that would reach the target. Mantle never runs that SQL. The author's agent makes the change with whatever it needs (SQL through the host's own tool, a data-copy Procedure run as the system caller, a dedupe script), and Mantle checks the database again. Storage is ready when no blocked difference remains.
|
|
41
|
-
|
|
42
|
-
There are no Mantle-written migration files for Schema tables and no destructive step Mantle performs on its own.
|
|
43
|
-
|
|
44
|
-
### 3. One path: boot converges
|
|
45
|
-
|
|
46
|
-
Core has one diff function and one place that calls it.
|
|
47
|
-
|
|
48
|
-
- **Boot** compares the plan fingerprint with the one stored in `_mantle_boot_state`. When they match, nothing is read. When they differ, boot introspects, applies the safe changes in one batch, stores the new fingerprint, and refuses to serve while a blocked change remains.
|
|
49
|
-
- **Concurrent cold starts** may race on the same change. A safe change that another isolate already applied (for example SQLite's duplicate-column error on `ADD COLUMN`) counts as applied, and the next introspection decides.
|
|
50
|
-
- **Cloud** keeps its deploy order (ADR-0024): Control calls the same Core function against the tenant database before it uploads the new Worker, then runs the canary. The new Worker's boot then finds a matching fingerprint and reads nothing. No migration file is involved.
|
|
51
|
-
- `mantle generate --check` prints the three classes against the local database, with the safe changes as SQL, and never writes. The printed SQL can be replayed: it uses `IF NOT EXISTS` wherever SQLite allows it, and `ADD COLUMN` is computed from the database's current state, because a host that applies migration files may fail a whole deploy on one failing statement (#1192).
|
|
52
|
-
- **Hosts that do not allow DDL from deployed code**, for whatever reason and however their rules change: Core does not model their migration mechanism. `mantle generate --check` prints the safe changes as SQL, the author's coding agent delivers them through the host's own path (a migration directory, a console, a deploy hook), and boot then finds the database converged and serves. Core ships no host-specific migration directory, journal or file format. What is known about a host (for example ChatGPT Sites, #1192) belongs in its consumer skill and docs, not in Core.
|
|
53
|
-
|
|
54
|
-
### 4. What stays versioned
|
|
55
|
-
|
|
56
|
-
- `_mantle_*` system tables and Core's product tables (`site_config`, `media_assets`, `pending_media_uploads`) keep canonical migrations in `_mantle_migrations`. Their shapes change with Mantle releases and sometimes need data moves (#1150); they are Mantle's own work and never the author's.
|
|
57
|
-
- mantle-auth keeps Better Auth's `getMigrations` for its tables.
|
|
58
|
-
- `_mantle_schema_tables` stays as the ownership registry: it names the tables Mantle created for Schemas, so a Schema never adopts an unrelated table (ADR-0032 decision 11). Its `projection` column is no longer an authority.
|
|
59
|
-
- Existing `schema-table-v2:*` ledger rows are left in place and no longer written.
|
|
60
|
-
|
|
61
|
-
### 5. Scope
|
|
62
|
-
|
|
63
|
-
The SQLite family (D1, Bun, libSQL) implements introspection. The IndexedDB adapter keeps its own object-store versioning; `MemoryStoreExecutor` has no storage to evolve.
|
|
64
|
-
|
|
65
|
-
> **Amendment (ADR-0034):** The IndexedDB adapter and `MemoryStoreExecutor` are removed. Convergence also creates the triggers that enforce Schema `checks` and foreign keys (`RESTRICT` only, and the triggers only `RAISE`), creates new Schema tables `STRICT`, and adds `_mantle_sequences`, `_mantle_tz`, and the `_mantle_fts_*` and `_mantle_geo_*` indexes behind `search` and `format: geo` to the system tables. Those indexes are Mantle's own and are rebuilt, not verified, when their declaration changes.
|
|
66
|
-
|
|
67
|
-
## Consequences
|
|
68
|
-
|
|
69
|
-
- Removed: `buildSqliteMigrationArtifact`, `renderSqliteManagedMigration`, `isAdditiveSchemaTableChange`, `coversSchemaTableProjection`, the managed read-only boot mode (`managedStorageFingerprint`), the append-only artifact and its `storage-fingerprint.json`, the #1080 reviewed-artifact contract, and the per-column ledger ids. `buildSqliteMigrationArtifact` and `isAdditiveSchemaTableChange` are public exports of `@aotter/mantle-runtime` 0.1.4, so their removal is a breaking change listed in the 0.2.0 release note; the rest shipped only in 0.1.5 alphas.
|
|
70
|
-
- #1011 is covered: undeclared indexes are visible on every diff.
|
|
71
|
-
- The Swolhalla unique-index case (#1080) becomes: create the new unique index, drop the old one, rerun the check. No new Schema, no abandoned table.
|
|
72
|
-
- **Cloud.** "Storage matches the plan" becomes a platform-verified fact (ADR-0032 decision 10), checked by introspection instead of by the list of scripts that ran. A tenant's agent cannot run SQL against a Cloud-owned database today, so Cloud keeps refusing blocked changes until aotter/mantle-home offers a channel for author-made changes; that is a mantle-home issue, not a Core blocker.
|
|
73
|
-
- Boot on a changed plan costs a few `PRAGMA` reads per Schema, once per fingerprint.
|
|
74
|
-
- ADR-0024's "operators rebuild the database" is replaced by decision 2. Its native-table layout, reserved names and ownership rules are unchanged.
|
|
75
|
-
|
|
76
|
-
## Alternatives
|
|
77
|
-
|
|
78
|
-
- **Keep the reviewed-artifact workflow** (#1080, #1086) and extend it case by case. Rejected: each new change kind needs its own artifact type and review path, and the files still drift from the database.
|
|
79
|
-
- **Let Mantle generate destructive migrations behind a flag.** Rejected: Mantle cannot know whether a removed field is a rename, a split or garbage, and a wrong guess loses data.
|
|
80
|
-
- **A planner per file-based host** (the CLI reads the remote database and writes that host's migration file). Rejected: Cloud calls the Core function directly, and other hosts' delivery rules change faster than Core releases; the agent bridges them from the printed SQL.
|
|
81
|
-
- **Diff against `_mantle_schema_tables` instead of the database.** Rejected: that is today's design, and it cannot see what the author or another tool changed.
|
|
82
|
-
- **Introspect on every boot.** Rejected: the fingerprint already says when the plan changed; cold starts should not pay for `PRAGMA` reads.
|
|
83
|
-
|
|
84
|
-
## How to apply
|
|
85
|
-
|
|
86
|
-
1. Build the introspection and diff in the Store storage layer (ADR-0032 decision 4), shared by boot, `mantle generate --check` and Cloud's deploy step.
|
|
87
|
-
2. Port the ADR-0024 conformance cases to the three classes, and add: an undeclared index is reported and kept; a failed unique index is blocked and applies nothing; a blocked change resolved by hand passes the next check; an unchanged fingerprint reads nothing; two boots racing on one `ADD COLUMN` both succeed.
|
|
88
|
-
3. Remove the artifact workflow, including `generate-sites.ts` and its `drizzle/` generation (ADR-0032 removes `--host`), in the same change that ships boot convergence, so there is never a release with neither. Move what the Sites handbook says about D1 migrations into the Sites consumer skill.
|
|
89
|
-
|
|
90
|
-
## Implementation status
|
|
91
|
-
|
|
92
|
-
Proposed.
|