@aotter/mantle 0.1.5-alpha.1 → 0.2.0-alpha.10
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 +166 -298
- package/dist/auth/adapter.d.ts +32 -0
- package/dist/auth/adapter.js +288 -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 +155 -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 +63 -0
- package/dist/auth/oauth.js +217 -0
- package/dist/auth/resource-seeds.js +10 -0
- package/dist/auth/routes.d.ts +32 -0
- package/dist/auth/routes.js +226 -0
- package/dist/build/compiler.d.ts +721 -0
- package/dist/build/compiler.js +7029 -0
- package/dist/build/spec/domain/model/ManifestGrammar.d.ts +439 -0
- package/dist/build/spec/domain/model/RuntimePlan.d.ts +168 -0
- package/dist/build/spec/domain/model/SqlIr.d.ts +129 -0
- package/dist/build/spec/domain/model/UserFields.d.ts +21 -0
- package/dist/build/spec/domain/service/PlanFingerprint.d.ts +7 -0
- package/dist/build/spec/kernel/diagnostic.d.ts +108 -0
- 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 +57 -0
- package/dist/domain/describe/chunk-ZVXBGP7Y.js +424 -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 +19 -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 +230 -0
- package/dist/domain/recipes.js +24 -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 +188 -0
- package/dist/infrastructure/cli.js +118 -0
- package/dist/infrastructure/generate.d.ts +12 -0
- package/dist/infrastructure/generate.js +189 -0
- package/dist/infrastructure/generateAuth.d.ts +8 -0
- package/dist/infrastructure/generateAuth.js +74 -0
- package/dist/infrastructure/help.js +60 -0
- package/dist/infrastructure/init.js +54 -0
- package/dist/infrastructure/inputs.js +41 -0
- package/dist/infrastructure/mounts.js +25 -0
- package/dist/infrastructure/wrangler.js +109 -0
- package/dist/kernel/authorization.d.ts +4 -0
- package/dist/kernel/authorization.js +16 -0
- package/dist/kernel/binds.d.ts +60 -0
- package/dist/kernel/binds.js +49 -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 +143 -0
- package/dist/kernel/contracts.js +97 -0
- package/dist/kernel/cron.d.ts +1 -0
- package/dist/kernel/cron.js +58 -0
- package/dist/kernel/dialect/common.d.ts +38 -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/drain.d.ts +5 -0
- package/dist/kernel/drain.js +35 -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 +99 -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/kernel/email.js +38 -0
- package/dist/kernel/host-access.d.ts +10 -0
- package/dist/kernel/host-access.js +65 -0
- package/dist/kernel/host-caller.d.ts +39 -0
- package/dist/kernel/host-caller.js +56 -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 +69 -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 +371 -0
- package/dist/kernel/mcp.d.ts +110 -0
- package/dist/kernel/mcp.js +50 -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/kernel/r2-media.d.ts +42 -0
- package/dist/kernel/r2-media.js +78 -0
- package/dist/kernel/rest-dispatch.js +38 -0
- package/dist/kernel/rest-router.js +64 -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 +44 -0
- package/dist/kernel/search.js +5 -0
- package/dist/kernel/site-types.d.ts +146 -0
- package/dist/kernel/site-types.js +1 -0
- package/dist/kernel/site.d.ts +39 -0
- package/dist/kernel/site.js +32 -0
- package/dist/kernel/store.d.ts +175 -0
- package/dist/kernel/store.js +269 -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 +35 -0
- package/dist/kernel/user-fields.js +81 -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-index.js +40 -0
- package/dist/kernel/web-response.js +8 -0
- package/dist/kernel/web.d.ts +77 -0
- package/dist/kernel/web.js +124 -0
- package/dist/kernel/where.js +27 -0
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/usecase/adminBindings.js +143 -0
- package/dist/usecase/adminClient.js +87 -0
- package/dist/usecase/adminDescriptors.js +107 -0
- package/dist/usecase/generate.js +166 -0
- package/dist/usecase/handlers.js +21 -0
- package/dist/usecase/mcp-media.js +17 -0
- package/dist/usecase/mcp.js +100 -0
- package/dist/usecase/paging.js +71 -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 +39 -0
- package/dist/usecase/stores.js +64 -0
- package/dist/usecase/tool-version.js +9 -0
- package/dist/usecase/translations.js +78 -0
- package/dist/usecase/ttl.js +20 -0
- package/dist/usecase/validation.js +241 -0
- package/dist/usecase/web.js +23 -0
- package/docs/examples/README.md +39 -18
- package/docs/examples/app-shell/.dev.vars.example +4 -0
- package/docs/examples/app-shell/README.md +121 -0
- package/docs/examples/app-shell/accept.mjs +91 -0
- package/docs/examples/app-shell/gitignore +7 -0
- package/docs/examples/app-shell/package.json +43 -0
- package/docs/examples/app-shell/pnpm-workspace.yaml +8 -0
- package/docs/examples/app-shell/smoke-kit.mjs +168 -0
- package/docs/examples/app-shell/src/auth.ts +58 -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 +14 -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/app-shell/tsconfig.json +26 -0
- package/docs/examples/app-shell/worker-configuration.d.ts +22 -0
- package/docs/examples/app-shell/wrangler.jsonc +62 -0
- package/docs/examples/club-events/README.md +65 -0
- package/docs/examples/club-events/manifests/club-events.yaml +247 -0
- package/docs/examples/club-events/smoke.mjs +127 -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 +78 -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 +8 -0
- package/docs/examples/purchasing/.dev.vars.example +6 -0
- package/docs/examples/purchasing/README.md +99 -0
- package/docs/examples/purchasing/manifests/purchasing.yaml +374 -0
- package/docs/examples/purchasing/seed.sql +4 -0
- package/docs/examples/purchasing/smoke.mjs +191 -0
- package/docs/examples/purchasing/src/admin.tsx +13 -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 +69 -0
- package/docs/examples/recipes/README.md +60 -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 +74 -0
- package/docs/handbook/cloudflare/authentication.md +180 -322
- package/docs/handbook/cloudflare/chatgpt-sites.md +5 -23
- package/docs/handbook/cloudflare/deploy-and-operate.md +55 -77
- package/docs/handbook/cloudflare/media-r2.md +61 -205
- package/docs/handbook/cloudflare/service-entry.md +239 -0
- package/docs/handbook/concepts/authorization.md +10 -107
- package/docs/handbook/concepts/four-atoms.md +9 -168
- package/docs/handbook/concepts/lifecycle-and-locales.md +9 -132
- package/docs/handbook/concepts/mcp-and-agents.md +24 -121
- package/docs/handbook/concepts/procedures-and-triggers.md +5 -217
- package/docs/handbook/concepts/runtime-and-adapters.md +15 -169
- package/docs/handbook/concepts/views.md +10 -185
- package/docs/handbook/examples/hub.md +3 -8
- package/docs/handbook/guides/adapter-guide.md +11 -0
- package/docs/handbook/guides/admin-ui.md +115 -133
- package/docs/handbook/guides/agent-setup.md +64 -74
- package/docs/handbook/guides/agent-workflow-acceptance.md +232 -0
- package/docs/handbook/guides/email.md +86 -0
- package/docs/handbook/guides/local-testing.md +40 -0
- package/docs/handbook/guides/mcp-apps.md +560 -0
- package/docs/handbook/guides/native-admin.md +566 -0
- package/docs/handbook/guides/native-execution.md +133 -0
- package/docs/handbook/guides/oauth.md +219 -0
- package/docs/handbook/guides/postgres-adapters.md +56 -0
- package/docs/handbook/guides/public-pages.md +87 -0
- package/docs/handbook/guides/size-and-startup.md +9 -0
- package/docs/handbook/guides/sql-patterns.md +266 -0
- package/docs/handbook/guides/typed-queries.md +211 -107
- package/docs/handbook/navigation.json +176 -55
- package/docs/handbook/reference/admin-descriptors.md +53 -0
- package/docs/handbook/reference/authorization.md +39 -266
- package/docs/handbook/reference/describe.md +56 -0
- package/docs/handbook/reference/diagnostics.md +19 -186
- package/docs/handbook/reference/features.md +45 -55
- package/docs/handbook/reference/manifest.md +6 -129
- package/docs/handbook/reference/procedure.md +11 -303
- package/docs/handbook/reference/schema.md +64 -240
- package/docs/handbook/reference/site-config.md +5 -218
- package/docs/handbook/reference/sql.md +64 -0
- package/docs/handbook/reference/surface.md +392 -201
- package/docs/handbook/reference/trigger.md +56 -192
- package/docs/handbook/reference/view.md +24 -243
- package/docs/handbook/releases/index.md +244 -77
- package/docs/handbook/start/agents.md +45 -0
- package/docs/handbook/start/overview.md +9 -48
- package/docs/handbook/start/project-and-cli.md +51 -104
- package/docs/handbook/start/quickstart-worker.md +43 -178
- package/docs/skills/develop/SKILL.md +79 -249
- package/docs/skills/integrate/SKILL.md +39 -50
- package/docs/skills/media-gc/SKILL.md +34 -10
- package/docs/skills/provision/SKILL.md +36 -186
- package/docs/skills/update/SKILL.md +23 -38
- package/docs/source/scripts/postgres-adapter.ts +101 -0
- package/docs/upgrade-0.1-to-0.2.md +227 -0
- package/package.json +120 -131
- package/skills/README.md +48 -108
- package/skills/mantle/SKILL.md +76 -0
- package/dist/admin-ui.d.ts +0 -2
- package/dist/admin-ui.d.ts.map +0 -1
- package/dist/admin-ui.js +0 -2
- package/dist/admin-ui.js.map +0 -1
- package/dist/admin.d.ts +0 -2
- package/dist/admin.d.ts.map +0 -1
- package/dist/admin.js +0 -2
- package/dist/admin.js.map +0 -1
- package/dist/auth.d.ts +0 -2
- package/dist/auth.d.ts.map +0 -1
- package/dist/auth.js +0 -2
- package/dist/auth.js.map +0 -1
- package/dist/bun.d.ts +0 -2
- package/dist/bun.d.ts.map +0 -1
- package/dist/bun.js +0 -2
- package/dist/bun.js.map +0 -1
- package/dist/cli/generate-cloudflare.d.ts +0 -7
- package/dist/cli/generate-cloudflare.d.ts.map +0 -1
- package/dist/cli/generate-cloudflare.js +0 -123
- package/dist/cli/generate-cloudflare.js.map +0 -1
- package/dist/cli/generate-project.d.ts +0 -25
- package/dist/cli/generate-project.d.ts.map +0 -1
- package/dist/cli/generate-project.js +0 -282
- package/dist/cli/generate-project.js.map +0 -1
- package/dist/cli/generate-sites.d.ts +0 -8
- package/dist/cli/generate-sites.d.ts.map +0 -1
- package/dist/cli/generate-sites.js +0 -273
- package/dist/cli/generate-sites.js.map +0 -1
- package/dist/cli/generate.d.ts +0 -20
- package/dist/cli/generate.d.ts.map +0 -1
- package/dist/cli/generate.js +0 -299
- package/dist/cli/generate.js.map +0 -1
- package/dist/cli/harness.d.ts +0 -3
- package/dist/cli/harness.d.ts.map +0 -1
- package/dist/cli/harness.js +0 -214
- package/dist/cli/harness.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 -77
- package/dist/cli/main.js.map +0 -1
- package/dist/cli/skills.d.ts +0 -3
- package/dist/cli/skills.d.ts.map +0 -1
- package/dist/cli/skills.js +0 -128
- package/dist/cli/skills.js.map +0 -1
- package/dist/cloudflare.d.ts +0 -2
- package/dist/cloudflare.d.ts.map +0 -1
- package/dist/cloudflare.js +0 -2
- package/dist/cloudflare.js.map +0 -1
- package/dist/codegen/emitMantleModule.d.ts +0 -22
- package/dist/codegen/emitMantleModule.d.ts.map +0 -1
- package/dist/codegen/emitMantleModule.js +0 -291
- package/dist/codegen/emitMantleModule.js.map +0 -1
- package/dist/codegen.d.ts +0 -2
- package/dist/codegen.d.ts.map +0 -1
- package/dist/codegen.js +0 -2
- package/dist/codegen.js.map +0 -1
- package/dist/runtime-testing.d.ts +0 -2
- package/dist/runtime-testing.d.ts.map +0 -1
- package/dist/runtime-testing.js +0 -2
- package/dist/runtime-testing.js.map +0 -1
- package/dist/runtime.d.ts +0 -2
- package/dist/runtime.d.ts.map +0 -1
- package/dist/runtime.js +0 -2
- package/dist/runtime.js.map +0 -1
- package/dist/spec.d.ts +0 -2
- package/dist/spec.d.ts.map +0 -1
- package/dist/spec.js +0 -2
- package/dist/spec.js.map +0 -1
- package/dist/vercel-libsql.d.ts +0 -2
- package/dist/vercel-libsql.d.ts.map +0 -1
- package/dist/vercel-libsql.js +0 -2
- package/dist/vercel-libsql.js.map +0 -1
- package/dist/vercel.d.ts +0 -2
- package/dist/vercel.d.ts.map +0 -1
- package/dist/vercel.js +0 -2
- package/dist/vercel.js.map +0 -1
- package/dist/web.d.ts +0 -2
- package/dist/web.d.ts.map +0 -1
- package/dist/web.js +0 -2
- package/dist/web.js.map +0 -1
- package/docs/adapter-guide.md +0 -222
- 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 -900
- 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 -240
- 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/README.md +0 -81
- 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 -42
- package/docs/adr/adr-lite-909-admin-ui-kit.md +0 -37
- package/docs/agent-prompts.md +0 -64
- package/docs/api-mcp-authorization.md +0 -5
- package/docs/assets/mantle-admin-developer.png +0 -0
- package/docs/assets/mantle-admin-operations.png +0 -0
- package/docs/assets/mantle-hero.jpg +0 -0
- package/docs/auth-hosting-model.md +0 -166
- package/docs/cloudflare-low-level-composition.md +0 -5
- package/docs/consumer-onboarding-audit.md +0 -65
- package/docs/deferred-lifecycle-queues.md +0 -5
- package/docs/design-atoms.md +0 -16
- package/docs/design-references/editorial-blog-2026-05-05.md +0 -218
- package/docs/direct-authoring.md +0 -5
- package/docs/examples/builtin-commerce.md +0 -269
- package/docs/examples/builtin-intake.md +0 -143
- package/docs/examples/builtin-legal-documents.md +0 -189
- package/docs/examples/builtin-procurement.md +0 -241
- package/docs/examples/builtin-publication.md +0 -241
- package/docs/examples/builtin-reservation.md +0 -149
- package/docs/examples/cf-primitives-commerce-inventory.md +0 -809
- package/docs/examples/cf-primitives-guarded-api.md +0 -429
- package/docs/examples/cf-primitives-intake-hooks.md +0 -319
- package/docs/examples/host-chatgpt-sites/.openai/hosting.json +0 -1
- package/docs/examples/host-chatgpt-sites/README.md +0 -70
- package/docs/examples/host-chatgpt-sites/drizzle/0000_sites_users.sql +0 -8
- package/docs/examples/host-chatgpt-sites/drizzle/0001_mantle.sql +0 -294
- package/docs/examples/host-chatgpt-sites/drizzle/0002_article_cover.sql +0 -5
- package/docs/examples/host-chatgpt-sites/drizzle/0003_store_instance_id.sql +0 -1
- package/docs/examples/host-chatgpt-sites/drizzle/0004_mantle.sql +0 -10
- package/docs/examples/host-chatgpt-sites/drizzle/0005_mantle.sql +0 -24
- package/docs/examples/host-chatgpt-sites/drizzle/meta/_journal.json +0 -1
- package/docs/examples/host-chatgpt-sites/drizzle/meta/mantle-state.json +0 -60
- package/docs/examples/host-chatgpt-sites/manifests/site.yaml +0 -27
- package/docs/examples/host-chatgpt-sites/package.json +0 -1
- package/docs/examples/host-chatgpt-sites/public/site.css +0 -1
- package/docs/examples/host-chatgpt-sites/scripts/build.mjs +0 -13
- package/docs/examples/host-chatgpt-sites/scripts/check.mjs +0 -101
- package/docs/examples/host-chatgpt-sites/scripts/migration.mjs +0 -43
- package/docs/examples/host-chatgpt-sites/src/chatgpt-auth.ts +0 -66
- package/docs/examples/host-chatgpt-sites/src/index.ts +0 -46
- package/docs/examples/host-chatgpt-sites/src/mcp.ts +0 -49
- package/docs/examples/host-chatgpt-sites/src/media.ts +0 -109
- package/docs/examples/host-chatgpt-sites/src/r2-lab.ts +0 -38
- package/docs/examples/host-chatgpt-sites/src/storage-fingerprint.json +0 -1
- package/docs/examples/host-chatgpt-sites/src/web.ts +0 -35
- package/docs/examples/host-chatgpt-sites/tsconfig.json +0 -1
- package/docs/examples/host-chatgpt-sites/wrangler.jsonc +0 -10
- package/docs/examples/host-local-admin-otp/.dev.vars.example +0 -3
- package/docs/examples/host-local-admin-otp/README.md +0 -80
- package/docs/examples/host-local-admin-otp/ensure-dev-vars.mjs +0 -5
- package/docs/examples/host-local-admin-otp/manifests/site.yaml +0 -25
- package/docs/examples/host-local-admin-otp/package.json +0 -29
- package/docs/examples/host-local-admin-otp/public/.gitkeep +0 -1
- package/docs/examples/host-local-admin-otp/smoke.mjs +0 -141
- package/docs/examples/host-local-admin-otp/src/index.ts +0 -54
- package/docs/examples/host-local-admin-otp/tsconfig.json +0 -17
- package/docs/examples/host-local-admin-otp/wrangler.jsonc +0 -23
- package/docs/examples/host-minimal-worker/README.md +0 -41
- package/docs/examples/host-minimal-worker/manifests/site.yaml +0 -25
- package/docs/examples/host-minimal-worker/package.json +0 -26
- package/docs/examples/host-minimal-worker/smoke.mjs +0 -23
- package/docs/examples/host-minimal-worker/src/index.ts +0 -4
- package/docs/examples/host-minimal-worker/tsconfig.json +0 -17
- package/docs/examples/host-minimal-worker/wrangler.jsonc +0 -22
- package/docs/handbook/chatgpt-sites/equipment-checkout.md +0 -231
- package/docs/handbook/chatgpt-sites/generated-app.md +0 -84
- package/docs/handbook/chatgpt-sites/host-reference.md +0 -113
- package/docs/handbook/chatgpt-sites/index.md +0 -133
- package/docs/handbook/cloudflare/bindings.md +0 -291
- package/docs/handbook/cloudflare/conventional-worker.md +0 -166
- package/docs/handbook/cloudflare/deferred-hooks-queues.md +0 -170
- package/docs/handbook/cloudflare/low-level-composition.md +0 -169
- package/docs/handbook/cloudflare/public-web.md +0 -144
- package/docs/handbook/cloudflare/site-chrome.md +0 -75
- package/docs/handbook/examples/commerce-transaction.md +0 -11
- package/docs/handbook/examples/commerce.md +0 -11
- package/docs/handbook/examples/guarded-api.md +0 -10
- package/docs/handbook/examples/intake-form.md +0 -12
- package/docs/handbook/examples/intake-hooks.md +0 -11
- package/docs/handbook/examples/legal-documents.md +0 -10
- package/docs/handbook/examples/procurement-approvals.md +0 -10
- package/docs/handbook/examples/publication.md +0 -10
- package/docs/handbook/examples/reservation.md +0 -10
- package/docs/handbook/start/quickstart-admin.md +0 -52
- package/docs/labels.md +0 -71
- package/docs/media-uploads.md +0 -5
- package/docs/migration-0.1.2.md +0 -13
- package/docs/performance-harness.md +0 -228
- package/docs/release-process.md +0 -244
- package/docs/schema-indexes.md +0 -5
- package/docs/sealed-pipeline-ownership.md +0 -101
- package/docs/skills/plugin/SKILL.md +0 -132
- package/docs/skills/theme/SKILL.md +0 -77
- package/docs/spec-only-host-adoption.md +0 -157
- package/docs/transaction-patterns.md +0 -5
- package/skills/develop/SKILL.md +0 -258
- package/skills/install/SKILL.md +0 -112
- package/skills/integrate/SKILL.md +0 -60
- package/skills/media-gc/SKILL.md +0 -85
- package/skills/plugin/SKILL.md +0 -132
- package/skills/provision/SKILL.md +0 -194
- package/skills/theme/SKILL.md +0 -77
- package/skills/update/SKILL.md +0 -51
- package/templates/chatgpt-sites/auth.ts +0 -66
- package/templates/chatgpt-sites/build.mjs +0 -14
- package/templates/chatgpt-sites/env.ts +0 -1
- package/templates/chatgpt-sites/mcp.ts +0 -48
- package/templates/chatgpt-sites/public-mcp.ts +0 -29
- package/templates/chatgpt-sites/smoke-local.mjs +0 -20
|
@@ -1,142 +1,19 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Choose between publishing and operational Schemas, and understand how site locales, localized Schemas and translation children fit together.
|
|
3
|
-
---
|
|
4
1
|
# Lifecycle and locales
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
Schemas default to `operational`: rows are live immediately and edit in place. Opt-in `publishing` adds `status` (draft/published/archived), nullable `published_at` and a scope-aware `(published_at, id)` index.
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
Generated `<table>.publish`, `.unpublish` and `.archive` Procedures take `{ id, expectedVersion }`, require admin/system and perform one atomic UPDATE. Publish checks required fields, visibility, TTL, source state and OCC. A failed guard is `CONFLICT`. Store cannot write status/published_at directly. Admin permits generic publishing edits only on drafts; Store does not add that separate Admin editing rule.
|
|
9
6
|
|
|
10
|
-
|
|
7
|
+
Public Views see published rows only. Other reads expose drafts only to admin/system. This policy applies to joins and nested queries too.
|
|
11
8
|
|
|
12
|
-
|
|
9
|
+
## Translations
|
|
13
10
|
|
|
14
|
-
|
|
11
|
+
`localized: true` declares a locale string. `translates: { parent, on }` declares a localized child sharing a join key with its parent. A scoped parent needs the same child scope column. A publishing translation can publish only when its caller-visible parent is published (or operational); the parent guard is inside the atomic UPDATE. Unpublishing a parent hides translations without changing their status.
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|---|---|
|
|
18
|
-
| `draft` | `published`, `archived` |
|
|
19
|
-
| `published` | `archived`, `draft` |
|
|
20
|
-
| `archived` | `draft` |
|
|
13
|
+
Store translation reads merge visible parent fields, with child fields taking precedence. Authored Views return only their SELECT outputs. Generated `translations.ts` exports `translationLocales(db, caller, parent, rows)` for a parent page (up to 500 storage-named rows); it uses batched authorized child reads rather than one query per parent. Stored locale values remain plain strings; site locales do not rewrite or validate them automatically.
|
|
21
14
|
|
|
22
|
-
|
|
23
|
-
|---|---|
|
|
24
|
-
| On create | `status: published` immediately |
|
|
25
|
-
| Editing | In place, in any status |
|
|
26
|
-
| Transitions | None. Publish, unpublish and archive all reject. |
|
|
15
|
+
SQLite/PostgreSQL interactive Store transactions refuse to combine translation publication and a parent status change in either order. D1 has no interactive Store transactions. The app owns consistency for native transactions outside Store.
|
|
27
16
|
|
|
28
|
-
|
|
17
|
+
## Expiry
|
|
29
18
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
### What each surface shows
|
|
33
|
-
|
|
34
|
-
| Surface | `publishing` | `operational` |
|
|
35
|
-
|---|---|---|
|
|
36
|
-
| Admin | Draft and published buckets, publish and unpublish controls, archive | Flat list, no lifecycle chrome; `uiSchema.list` supplies the columns |
|
|
37
|
-
| Staff MCP | `create_draft_<schema>`, `update_draft_<schema>` | `create_record_<schema>`, `update_record_<schema>` |
|
|
38
|
-
| Staff MCP, both modes | `request_publish`, `unpublish_entry`, `archive_entry`, `delete_entry` | same generic lifecycle tools |
|
|
39
|
-
|
|
40
|
-
### Procedure-managed collections
|
|
41
|
-
|
|
42
|
-
Root `schema.readOnly: true` marks a collection whose authority lives in its declared Procedures, not in generic authoring. Staff MCP emits no `create_*` or `update_*` tool for it, and Admin's generic create, update, status change and delete return `CONFLICT` with a message saying the Schema is read-only on generic authoring surfaces. Declared Views and Procedures keep working. Use it for operational mirrors, projections and audit rows.
|
|
43
|
-
|
|
44
|
-
## Locales in three layers
|
|
45
|
-
|
|
46
|
-
Localization is not one switch. Three independent layers have to agree.
|
|
47
|
-
|
|
48
|
-
| Layer | Where | What it decides |
|
|
49
|
-
|---|---|---|
|
|
50
|
-
| `Schema.spec.localized` | Manifest | Whether rows of this collection may carry `data.locale` |
|
|
51
|
-
| `site_config.locales` | Adapter `siteDefaults.locales`, boot-synced into the `site_config` row | Which locale tags exist for this deployment; the first entry is the canonical locale |
|
|
52
|
-
| `data.locale` | The entry | Which locale this particular row is |
|
|
53
|
-
|
|
54
|
-
`siteDefaults.locales` is code-owned: Core rewrites the stored row at boot whenever the declared list differs, so the code stays canonical. Brand, title and description seed once and are then edited through site settings. See [Site defaults and site_config](../reference/site-config.md).
|
|
55
|
-
|
|
56
|
-
### Canonical tags
|
|
57
|
-
|
|
58
|
-
Mantle accepts a deliberately narrow subset of BCP 47: a two- or three-letter language, plus an optional two-letter region. Mixed spellings are canonicalized, so `zh-tw`, `ZH_TW` and `zhTW` all become `zh-TW`, and the list is deduplicated in place. Anything else fails at boot with `InvalidSiteDefaultsError`.
|
|
59
|
-
|
|
60
|
-
> **Script subtags are unsupported**
|
|
61
|
-
> `zh-Hant`, `zh-Hans`, `sr-Latn` and `sr-Cyrl` are valid BCP 47 but rejected in this version. Use region tags: `zh-TW` for Traditional Chinese, `zh-CN` for Simplified.
|
|
62
|
-
|
|
63
|
-
### The write-time gate
|
|
64
|
-
|
|
65
|
-
Every authoring path — Admin, Staff MCP and builtin Procedures — runs the same guard, per request, against the current site locales.
|
|
66
|
-
|
|
67
|
-
| Condition | Result |
|
|
68
|
-
|---|---|
|
|
69
|
-
| Non-localized Schema, `data.locale` present | `INPUT_VALIDATION_FAILED` |
|
|
70
|
-
| Localized Schema, `data.locale` missing or empty | `INPUT_VALIDATION_FAILED`, skipped for partial draft saves |
|
|
71
|
-
| Localized Schema, `data.locale` not in the site locales | `INPUT_VALIDATION_FAILED`, with the enabled locales as candidates |
|
|
72
|
-
| Site locales list is empty | Membership is not checked |
|
|
73
|
-
|
|
74
|
-
`locale` is a reserved data field. A non-localized Schema that declares it is rejected outright; when such a Schema genuinely needs a language value, name it after its domain meaning — `replyLocale` on a support ticket, `orderLocale` on an order — and validate it with an `enum` like any other field.
|
|
75
|
-
|
|
76
|
-
### Boot checks versus per-request resolution
|
|
77
|
-
|
|
78
|
-
Boot validates shape only: the locale tags canonicalize, every `translates` reference resolves, and a `localized: true` Schema has at least one site locale (`SCHEMA_LOCALIZED_REQUIRES_SITE_LOCALES`). The active locale set is read from `site_config` per request, so changing the list does not require a redeploy of the manifest — but it does require the code-owned `siteDefaults` to agree, because boot resynchronizes the row.
|
|
79
|
-
|
|
80
|
-
## Versions of one entity versus independent rows
|
|
81
|
-
|
|
82
|
-
Two shapes are legal, and the choice is about identity, not about language count.
|
|
83
|
-
|
|
84
|
-
**A standalone localized Schema** treats each locale row as an independent record. Use it when nothing is shared between languages except a naming convention. A blog whose translations are independent posts does this: one localized `posts` Schema with `uniqueIndexes: [[slug, locale]]`.
|
|
85
|
-
|
|
86
|
-
**A non-localized parent plus a localized `translates` child** treats locale rows as versions of one entity. Use it when several rows describe the same thing and editors need to see which languages are missing. Only this shape powers Admin's translation grouping and completeness; Admin renders the child as locale tabs inside the parent's editor rather than as its own collection.
|
|
87
|
-
|
|
88
|
-
```yaml
|
|
89
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
90
|
-
kind: Schema
|
|
91
|
-
metadata:
|
|
92
|
-
name: products
|
|
93
|
-
spec:
|
|
94
|
-
title: Products
|
|
95
|
-
localized: false
|
|
96
|
-
lifecycle: publishing
|
|
97
|
-
uniqueIndexes: [[sku]]
|
|
98
|
-
schema:
|
|
99
|
-
type: object
|
|
100
|
-
additionalProperties: false
|
|
101
|
-
required: [sku, priceMinor]
|
|
102
|
-
properties:
|
|
103
|
-
sku: { type: string, pattern: "^[A-Z0-9-]+$" }
|
|
104
|
-
priceMinor: { type: integer, x-mcp-hint: money-minor }
|
|
105
|
-
---
|
|
106
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
107
|
-
kind: Schema
|
|
108
|
-
metadata:
|
|
109
|
-
name: product-translations
|
|
110
|
-
spec:
|
|
111
|
-
title: Product translations
|
|
112
|
-
localized: true
|
|
113
|
-
translates: { parent: products, on: sku }
|
|
114
|
-
lifecycle: publishing
|
|
115
|
-
uniqueIndexes: [[sku, locale]]
|
|
116
|
-
indexes: [[locale, sku]]
|
|
117
|
-
schema:
|
|
118
|
-
type: object
|
|
119
|
-
additionalProperties: false
|
|
120
|
-
required: [sku, name]
|
|
121
|
-
properties:
|
|
122
|
-
sku: { type: string, pattern: "^[A-Z0-9-]+$" }
|
|
123
|
-
locale: { type: string }
|
|
124
|
-
name: { type: string, minLength: 1 }
|
|
125
|
-
summary: { type: string, x-mcp-hint: markdown }
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
The parent holds what every language shares and stays non-localized. The child sets `localized: true`, declares `locale` without listing it in `required` — the write-time gate enforces presence — and owns at least one content field besides the join field and `locale`. A parent that is itself localized, a missing join field on either side, or a child with no content field are all rejected at parse or validate time; the codes are listed in the [Schema reference](../reference/schema.md#translates).
|
|
129
|
-
|
|
130
|
-
When you keep parallel locale rows in step, translate display strings only. Field names, option values, step identifiers and result keys must stay identical across locales, or the same View and the same MCP tool stop describing the same thing.
|
|
131
|
-
|
|
132
|
-
The full worked version of this pattern, with a locale-parameterized public View and its REST response, is [Publication](../../examples/builtin-publication.md).
|
|
133
|
-
|
|
134
|
-
## Source
|
|
135
|
-
|
|
136
|
-
- [`packages/mantle-spec/src/domain/service/LifecycleStateMachine.ts`](../../../packages/mantle-spec/src/domain/service/LifecycleStateMachine.ts)
|
|
137
|
-
- [`packages/mantle-spec/src/domain/service/LocaleCanonicalizer.ts`](../../../packages/mantle-spec/src/domain/service/LocaleCanonicalizer.ts)
|
|
138
|
-
- [`packages/mantle-spec/src/domain/service/SiteDefaultsValidator.ts`](../../../packages/mantle-spec/src/domain/service/SiteDefaultsValidator.ts)
|
|
139
|
-
- [`packages/mantle-spec/src/domain/model/SiteConfig.ts`](../../../packages/mantle-spec/src/domain/model/SiteConfig.ts)
|
|
140
|
-
- [`packages/mantle-runtime/src/domain/service/io/EntryWriteGuard.ts`](../../../packages/mantle-runtime/src/domain/service/io/EntryWriteGuard.ts)
|
|
141
|
-
- [`packages/mantle-runtime/src/infrastructure/mcp/McpToolCatalog.ts`](../../../packages/mantle-runtime/src/infrastructure/mcp/McpToolCatalog.ts)
|
|
142
|
-
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
19
|
+
TTL hides expired rows but does not delete them. Use generated system-only `<schema>.sweepExpired` from an application scheduler; [TTL maintenance](../guides/native-execution.md#ttl-maintenance) defines limits and cursors. Until removed, expired rows still occupy unique keys.
|
|
@@ -1,134 +1,37 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Mantle serves /mcp and /mcp/staff from the same Manifest — tool naming, the OAuth model, connecting a client, llms.txt, WebMCP and skills.
|
|
3
|
-
---
|
|
4
1
|
# MCP and agents
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
Mount generated `mcp()` with the app's native handle and verified Caller resolver. The official MCP SDK loads only on a matching request. Optional auth stays behind the application's dynamic auth import.
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
| Endpoint | Tools |
|
|
6
|
+
| --- | --- |
|
|
7
|
+
| `/mcp` | Public Views and Procedures exposed by public MCP Triggers |
|
|
8
|
+
| `/mcp/admin` | Admin Views, admin Trigger Procedures, generated publishing transitions and selected product tools |
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|---|---|---|
|
|
12
|
-
| `/mcp` | Any caller the site's HTTP routes would accept: OAuth bearer, same-origin cookie session, or anonymous. Each tool's `requires` decides; a `tools/call` that needs identity answers `401` with the OAuth challenge | Views with `surface: public`, and Procedures reached by an MCP Trigger with `surface: public` |
|
|
13
|
-
| `/mcp/staff` | Authenticated caller holding a staff role | Views with `surface: staff`, the generic authoring tools (rank-gated at `tools/call`), Procedures reached by an MCP Trigger with `surface: staff` |
|
|
10
|
+
Names are snake-case; a View named `my-orders` becomes `my_orders`. Each call retains declared authorization, scoped/TTL/publication SQL and input checks. Admin tools require admin authority. Tool visibility and UI hints grant no authority. Cookie-session mutations retain origin checks.
|
|
14
11
|
|
|
15
|
-
|
|
12
|
+
Views return structured `{ rows, nextCursor? }`. SQL Procedures retain native `{ results }`; application ref results remain app-owned. Selected boundaries redact native errors. Never retry an uncertain write automatically.
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
The app owns OAuth configuration, discovery and consent; follow [OAuth](../guides/oauth.md) and [authentication](../cloudflare/authentication.md). Public anonymous reads can avoid auth entirely; invalid supplied credentials cannot become anonymous. Authority-sensitive endpoints retain fresh primary checks.
|
|
18
15
|
|
|
19
|
-
|
|
16
|
+
[MCP Apps](../guides/mcp-apps.md) add static UI resources through the public contributor hook. Admin uses the same hook from its separate package. Credentials never go in App HTML. WebMCP catalogues are generated display/tool metadata for the mounted Admin product; server checks remain authoritative.
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|---|---|---|
|
|
23
|
-
| `query_view_<segment>` | Public or staff View (never internal) | The View's own `surface` |
|
|
24
|
-
| `create_draft_<schema>`, `update_draft_<schema>` | A Schema with `lifecycle: publishing` | Staff |
|
|
25
|
-
| `create_record_<schema>`, `update_record_<schema>` | A Schema with `lifecycle: operational` | Staff |
|
|
26
|
-
| `request_publish`, `unpublish_entry`, `archive_entry`, `delete_entry` | Present when an applicable Schema exists | Staff |
|
|
27
|
-
| `create_media_upload`, `commit_media_upload` | Media storage bound and at least one purpose declared | Staff |
|
|
28
|
-
| `<procedure segment>` | A Trigger with `source.kind: mcp` | The Trigger's `source.surface` |
|
|
18
|
+
See [surface contracts](../reference/surface.md) for tool schemas, challenges and scalar conversion.
|
|
29
19
|
|
|
30
|
-
|
|
20
|
+
## When a host shows old tools
|
|
31
21
|
|
|
32
|
-
|
|
22
|
+
A fresh `tools/list` always returns the deployed tools, but many hosts keep their own copy and do not ask again after a deploy. Mantle sends no list-changed notifications: tools change only at deploy, and the hosts that keep copies do not act on them. Instead each generated tool's description ends with its own version, and the results of a call that reaches the tool carry the deployed version, so a model holding an older definition can see it, correct its call or ask the user to refresh. Failures also state the input schema the tool is listed with now, except authorization refusals. A call naming a tool the catalogue no longer has gets the protocol's unknown-tool error, whose message gives `serverInfo.version`: unless the application sets it, a hash of every tool the endpoint serves, before per-caller filtering. Refusals before a call reaches its tool, such as authentication challenges, carry neither.
|
|
33
23
|
|
|
34
|
-
|
|
24
|
+
In Admin, WebMCP results from the tool route carry the version, and refusals add it with the input schema, except authorization refusals; a tool removed since the page loaded is refused as not found, without a catalogue version. Admin's two navigation tools, `admin_get_context` and `admin_navigate`, carry no version: the page defines and runs them without a server call, so it cannot list one definition and run another, and a reload after a deploy replaces both. The exact shapes are in [surface contracts](../reference/surface.md#tool-versions).
|
|
35
25
|
|
|
36
|
-
|
|
26
|
+
How each client refreshes its copy (as of 2026-10):
|
|
37
27
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
Prefer the client's native remote HTTP and OAuth support. Use a standard HTTP-to-stdio bridge only when the client accepts stdio MCP servers and cannot connect to remote HTTP directly:
|
|
49
|
-
|
|
50
|
-
```sh
|
|
51
|
-
npx -y mcp-remote http://localhost:8787/mcp
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
Mantle owns no local proxy and no auth-bypass mode. After connecting, inspect `tools/list`, then make one read-only `query_view_*` call before invoking any mutation — it proves the credential, the surface and the data path in one step that cannot damage anything. Use project-scoped client configuration where the client offers it, and never commit OAuth tokens or the bridge's token cache.
|
|
55
|
-
|
|
56
|
-
> **Discovery is not enforcement**
|
|
57
|
-
> `tools/list` filtering is UX. Every `tools/call` re-evaluates the manifest predicates and the guard through the same evaluator REST uses, so a guessed tool name gains nothing. See [Authorization](./authorization.md).
|
|
58
|
-
|
|
59
|
-
## The agent-readable web surface
|
|
60
|
-
|
|
61
|
-
When a Worker mounts public pages, the same content is served in a form agents can read without parsing HTML:
|
|
62
|
-
|
|
63
|
-
- **Markdown mirrors.** Every entry page has a `.md` twin at the same path, and entry pages advertise it with `<link rel="alternate" type="text/markdown">`.
|
|
64
|
-
- **`llms.txt` indexes.** `GET /llms.txt` lists the site; `GET /:locale/llms.txt` lists one locale. Pages hold 50 entries, ordered `updatedAt DESC, id DESC`, with a forward `cursor`, a `Link: ...; rel="next"` header and a `## Continue` section.
|
|
65
|
-
- **Sitemap.** `GET /sitemap.xml` returns a urlset, or an index linking `/sitemap.xml?part=1&cursor=...` parts of up to 2,000 URLs each.
|
|
66
|
-
|
|
67
|
-
Only `status: published` entries appear anywhere in that set. Details are in [Public web, SEO and cache](../cloudflare/public-web.md).
|
|
68
|
-
|
|
69
|
-
## WebMCP in the browser
|
|
70
|
-
|
|
71
|
-
### Admin: tools for the signed-in staff member
|
|
72
|
-
|
|
73
|
-
Admin UI registers staff tools in browsers supporting `document.modelContext`.
|
|
74
|
-
The catalog comes from `GET /admin/api/webmcp`; calls use
|
|
75
|
-
`POST /admin/api/mcp` with the current staff session. Server-side role checks,
|
|
76
|
-
Procedure authorization, and optimistic concurrency remain in force.
|
|
77
|
-
`admin_get_context` and `admin_navigate` add page context and navigation.
|
|
78
|
-
The WebMCP control appears after registration succeeds; unsupported browsers
|
|
79
|
-
can continue using the regular Admin UI.
|
|
80
|
-
|
|
81
|
-
Owners can explore application API documentation in Developer UI:
|
|
82
|
-
`/admin/dev/docs/api` for HTTP, `/admin/dev/docs/mcp` for remote MCP, and
|
|
83
|
-
`/admin/dev/docs/webmcp` for the Admin catalog and public-page capabilities.
|
|
84
|
-
These pages show projected definitions. Remote clients connect to the host's
|
|
85
|
-
advertised MCP endpoints using the authentication described above.
|
|
86
|
-
See the [Admin API guide](../../../packages/mantle-admin/README.md#admin-webmcp).
|
|
87
|
-
|
|
88
|
-
### Public pages: opt-in registration
|
|
89
|
-
|
|
90
|
-
`@aotter/mantle-web/webmcp` exposes public capabilities as tools inside a page, for browsers implementing the draft imperative WebMCP API. Importing the subpath has no side effect; registration starts only when `bindWebMcp()` is called.
|
|
91
|
-
|
|
92
|
-
```ts
|
|
93
|
-
import { bindWebMcp } from "@aotter/mantle-web/webmcp";
|
|
94
|
-
|
|
95
|
-
const binding = await bindWebMcp();
|
|
96
|
-
// later, when the page or app scope ends
|
|
97
|
-
binding.dispose();
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
It feature-detects `document.modelContext` and returns `{ supported: false }` on browsers without it. This public-page binding registers only public capabilities. Staff tools use the separate authenticated Admin integration above. Existing host tool names are inspected and skipped, never replaced. A server-backed page discovers the safe descriptors published at `GET /api/views` and calls the same-origin `GET /api/views/<name>` routes; a browser-local SPA passes `projectCallableCapabilities(plan, { surface: "public" })` and its own invoker. Procedure tools must still originate from an explicit public MCP Trigger, and invocation enters the runtime through that Trigger, so browser tools cannot bypass validation or authorization. See [Runtime pipeline and adapters](./runtime-and-adapters.md).
|
|
101
|
-
|
|
102
|
-
## Skills for your coding agent
|
|
103
|
-
|
|
104
|
-
The installed SDK ships version-matched instructions for agents working on a Mantle project. Project them into the repository:
|
|
105
|
-
|
|
106
|
-
```sh
|
|
107
|
-
pnpm exec mantle skills
|
|
108
|
-
pnpm exec mantle skills --check
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
This copies every skill the installed package marks `projection: project` — the develop skill among them — into matching `.agents/skills/mantle-*` and `.claude/skills/mantle-*` paths. Both layouts receive identical bytes; `--check` detects drift without writing. Skills that act destructively or target one platform stay out of that set and are opt-in. Manifest generation never rewrites agent instructions.
|
|
112
|
-
|
|
113
|
-
The bootstrap `mantle` skill is also available from the plugin marketplace.
|
|
114
|
-
The ongoing workflows come from the installed SDK through `mantle skills`:
|
|
115
|
-
|
|
116
|
-
```sh
|
|
117
|
-
# Canonical
|
|
118
|
-
npx skills add aotter/mantle
|
|
119
|
-
|
|
120
|
-
# Claude Code — two separate prompts
|
|
121
|
-
/plugin marketplace add aotter/mantle
|
|
122
|
-
/plugin install mantle@mantle
|
|
123
|
-
```
|
|
124
|
-
|
|
125
|
-
Never point a versioned project at a mutable branch. See [Project layout and the CLI loop](../start/project-and-cli.md).
|
|
126
|
-
|
|
127
|
-
## Source
|
|
128
|
-
- [`docs/adapter-guide.md`](../../../docs/adapter-guide.md)
|
|
129
|
-
- [`docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md`](../../../docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md)
|
|
130
|
-
- [`packages/mantle-spec/src/domain/service/McpToolNaming.ts`](../../../packages/mantle-spec/src/domain/service/McpToolNaming.ts)
|
|
131
|
-
- [`packages/mantle-web/README.md`](../../../packages/mantle-web/README.md)
|
|
132
|
-
- [`packages/mantle/README.md`](../../../packages/mantle/README.md)
|
|
133
|
-
- [`packages/adapters/cloudflare/README.md`](../../../packages/adapters/cloudflare/README.md)
|
|
134
|
-
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
28
|
+
| Client | Refresh |
|
|
29
|
+
| --- | --- |
|
|
30
|
+
| claude.ai connectors | A server-side copy keyed by URL, kept about an hour (users report up to 24 hours). Only adding the connector again under a new URL, such as `?v=2`, forces a refresh, and that needs authorization again. |
|
|
31
|
+
| Claude Code | `/mcp` reconnect, or a new session |
|
|
32
|
+
| ChatGPT developer mode | Refresh the connection, then start a new chat |
|
|
33
|
+
| Published ChatGPT apps | A daily scan, or Rescan, followed by review; keep tools compatible meanwhile |
|
|
34
|
+
| Cursor | Quit fully and reopen |
|
|
35
|
+
| VS Code | Run "MCP: Reset Cached Tools", or restart the server |
|
|
36
|
+
| Gemini CLI | `/mcp reload` |
|
|
37
|
+
| MCP Inspector | The refresh button |
|
|
@@ -1,221 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
description: How writes work — typed Procedures with a code seam, the three Trigger kinds that bind them, builtin ops, lifecycle hooks and the HTTP envelope.
|
|
3
|
-
---
|
|
4
|
-
# Writes: Procedures, Triggers and lifecycle hooks
|
|
1
|
+
# Writes: Procedures and Triggers
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
Writes use Store or declared Procedures. Raw SQL writes bypass scope, TTL, publishing and system-column rules.
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
SQL Procedures compile to native statements and return `{ results }`, one row array per statement. Row operations must affect exactly one row; a stale explicit version lock or unique clash is `CONFLICT`. Multi-statement Procedures run atomically; single-statement writes use native autocommit. See [native execution](../guides/native-execution.md) for uncertain outcomes. Never retry an `OUTCOME_UNKNOWN` write automatically.
|
|
9
6
|
|
|
10
|
-
A Procedure
|
|
7
|
+
A ref Procedure generates a typed `Handlers` key. Its handler receives `(ctx, input)` with `{ caller, db, store }` bound to the same Caller and transaction. Generated `requires` runs first. Handlers own side effects and their transaction boundaries.
|
|
11
8
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
The Procedure is also the only atom with a code seam. `handler: { kind: ref, ref: <key> }` names an opaque registration key — not a file path — that your project maps to a function in its `handlers` object. A key with no registered function fails at boot with `HANDLER_NOT_REGISTERED`.
|
|
15
|
-
|
|
16
|
-
## A Trigger is the only binding
|
|
17
|
-
|
|
18
|
-
`Trigger.spec.target.procedure` names a declared Procedure; `spec.source` says what reaches it. There are three source kinds.
|
|
19
|
-
|
|
20
|
-
| `source.kind` | Binds to | Notes |
|
|
21
|
-
|---|---|---|
|
|
22
|
-
| `http` | `method` and `path` | `POST`, `PUT`, `PATCH`, `DELETE` only. `GET` is absent because reads belong to [Views](./views.md). The path must start `/api/`, must not collide with another Trigger or an adapter-reserved prefix, and may use OpenAPI `{param}` segments that auto-bind to same-named input fields. |
|
|
23
|
-
| `mcp` | `surface: public` or `staff` | The tool is named after the Procedure, lowercased with hyphens replaced by underscores. Surface controls discovery only; `requires` is re-evaluated on every `tools/call`. |
|
|
24
|
-
| `lifecycle` | `schema`, `on: [<hook>]`, optional `errorPolicy` | Fires around entry mutations. See [Lifecycle hooks](#lifecycle-hooks). |
|
|
25
|
-
|
|
26
|
-
One Procedure may carry several Triggers, and that is how the same handler becomes an HTTP endpoint, an MCP tool and a hook without duplicated logic. Adding a transport is additive: write another Trigger, leave the Procedure alone.
|
|
27
|
-
|
|
28
|
-
## Builtin or `ref`
|
|
29
|
-
|
|
30
|
-
`handler.kind: builtin` is a thin shortcut over the storage adapter. The rule is simple: **use `builtin` when the body of the operation is "insert a row", "update a row" or "delete a row"; reach for `ref` when there is real business logic.** A guard Procedure can never be builtin.
|
|
31
|
-
|
|
32
|
-
| `op` | What it does | Input contract |
|
|
33
|
-
|---|---|---|
|
|
34
|
-
| `create` | Projects `input ∩ Schema.properties`, stamps `x-mantle-bind` fields, inserts. Status is `draft`, or `published` for an operational Schema. Returns the created `EntryRow`. | An object schema |
|
|
35
|
-
| `update` | Loads, merges the patch, bumps `version` under optimistic concurrency using the caller's observed `expectedVersion` (not `version+1`) | `id` (strict string) and `expectedVersion` (strict number), both required |
|
|
36
|
-
| `upsert` | With `match`, looks the row up by natural key: update with the caller token, or create when no row exists and no version was sent | `match` equals one `uniqueIndexes` tuple exactly, in order; no `id`; `expectedVersion` declared as strict number but not globally required |
|
|
37
|
-
| `delete` | Hard delete by id | `id` (strict string) required |
|
|
38
|
-
| `archive` | Transitions to `archived`, or `CONFLICT` if the machine disallows it | `id` required; publishing Schemas only |
|
|
39
|
-
|
|
40
|
-
`request_publish` and `publish` are deliberately not builtin ops. They are lifecycle operations, not CRUD primitives.
|
|
41
|
-
|
|
42
|
-
Every builtin write runs the same guards: locale gate, then a unique-index preflight. A race that slips past the preflight is caught by the database constraint and surfaces as `CONFLICT` (409) with no automatic retry.
|
|
43
|
-
|
|
44
|
-
### Side-channel input fields
|
|
45
|
-
|
|
46
|
-
A Procedure's `input` is the contract with the caller, not with the Schema. It may declare fields the Schema does not — a Turnstile token, a honeypot value, a referrer. The builtin op projects `input ∩ Schema.properties` and silently drops the rest, so nothing extra is stored.
|
|
47
|
-
|
|
48
|
-
Those fields are still readable where it matters: a `before_create` or `before_update` hook receives the **original, pre-projection** input. Every `after_*` hook receives only the persisted `entry.data`. That asymmetry is why bot checks are `before_*` hooks and notifications are `after_*` hooks.
|
|
49
|
-
|
|
50
|
-
## Lifecycle hooks
|
|
51
|
-
|
|
52
|
-
| Hook | Fires | Default `errorPolicy` |
|
|
53
|
-
|---|---|---|
|
|
54
|
-
| `before_create` | Before insert | `abort` |
|
|
55
|
-
| `after_create` | After insert | `continue` |
|
|
56
|
-
| `before_update` | Before an update, or a status transition whose target is not `published` | `abort` |
|
|
57
|
-
| `after_update` | After an update, or a status transition whose target is not `published` | `continue` |
|
|
58
|
-
| `before_delete` | Before delete | `abort` |
|
|
59
|
-
| `after_delete` | After delete | `continue` |
|
|
60
|
-
| `before_publish` | Before a transition to `published` | `abort` |
|
|
61
|
-
| `after_publish` | After a transition to `published` | `continue` |
|
|
62
|
-
|
|
63
|
-
> **Update hooks are not edit-only**
|
|
64
|
-
> There are no unpublish-specific or archive-specific hooks. `before_update` and `after_update` also fire for unpublish, archive and every other transition whose target is not `published`. A hook that assumes "the row was edited" will run on state changes you did not intend.
|
|
65
|
-
|
|
66
|
-
`abort` means a throwing handler cancels the surrounding mutation and the caller receives `LIFECYCLE_HOOK_REJECTED` (409). `continue` means the committed mutation stands: on the inline or `waitUntil` path the failure is logged and swallowed. Authors may set `errorPolicy` explicitly, but `abort` is rejected on a Trigger whose `on` list contains any `after_*` hook — a committed write cannot be un-committed.
|
|
67
|
-
|
|
68
|
-
Hooks are wired through the entry repository, so Admin, Staff MCP and builtin Procedures all fire the same hooks. When several lifecycle Triggers bind the same schema and hook, they fire **alphabetically by `Trigger.metadata.name`**; number them (`010-bot-check`, `020-rate-limit`) so the order is visible.
|
|
69
|
-
|
|
70
|
-
Handlers receive `ctx.event = { id, trigger, hook, schema, entry }`. `id` is stable across retries, `trigger` is the current Trigger name, and `entry` is `null` only for `before_create`; otherwise it is the pre-mutation row for `before_*` and the persisted row for `after_*`.
|
|
71
|
-
|
|
72
|
-
### Deferred `after_*` delivery
|
|
73
|
-
|
|
74
|
-
With an optional `DeferredHookDispatcher`, `after_*` hooks leave the request path and run under the delivery adapter's at-least-once retry and dead-letter policy instead of being swallowed. Delivery is not transactional with the database and exactly-once is not promised, so handlers must be idempotent; the conventional key is `${ctx.event.id}:${ctx.event.trigger}`. Cloudflare wiring, the envelope and DLQ configuration are in [Deferred hooks with Queues](../cloudflare/deferred-hooks-queues.md).
|
|
75
|
-
|
|
76
|
-
## The HTTP envelope
|
|
77
|
-
|
|
78
|
-
An HTTP Trigger wraps the handler's result as `{ "ok": true, "data": <result> }`, or returns the redacted diagnostic with the code's mapped status:
|
|
79
|
-
|
|
80
|
-
```json
|
|
81
|
-
{ "ok": false, "diagnostic": { "code": "INPUT_VALIDATION_FAILED", "path": "POST /api/contact#/name" } }
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
For a builtin `create`, `data` is the whole `EntryRow`: `id`, `collection`, `status`, `version`, `data`, nullable `authorId`, millisecond `createdAt` and `updatedAt`, and `locale` on localized rows. Declare `spec.output` against that row, not against the envelope. The request body must be a JSON object; anything else is a 400, and an oversize body is a 413.
|
|
85
|
-
|
|
86
|
-
| Code | HTTP | When |
|
|
87
|
-
|---|---|---|
|
|
88
|
-
| `INPUT_VALIDATION_FAILED` | 400 | Input fails the converted schema, or the body is not a JSON object |
|
|
89
|
-
| `UNAUTHENTICATED` | 401 | No verified credential at all |
|
|
90
|
-
| `ENTITLEMENT_REQUIRED` | 402 | A guard Procedure denied the current business entitlement |
|
|
91
|
-
| `AUTH_DENIED` | 403 | Authenticated, but a `requires.auth` predicate was false |
|
|
92
|
-
| `NOT_FOUND` | 404 | Unknown entry id or View name |
|
|
93
|
-
| `CONFLICT` | 409 | Illegal lifecycle transition, or a unique-index collision |
|
|
94
|
-
| `LIFECYCLE_HOOK_REJECTED` | 409 | A `before_*` hook aborted the mutation |
|
|
95
|
-
| `OUTPUT_VALIDATION_FAILED` | 500 | The handler returned a value its `output` schema rejects |
|
|
96
|
-
| `HANDLER_NOT_REGISTERED` | 500 | A `ref` key has no registered function |
|
|
97
|
-
| `INTERNAL_ERROR` | 500 | Uncaught handler exception |
|
|
98
|
-
|
|
99
|
-
The full catalog is in [Diagnostic codes](../reference/diagnostics.md).
|
|
100
|
-
|
|
101
|
-
## Worked example: a contact form
|
|
102
|
-
|
|
103
|
-
One builtin write, one `before_create` check that can abort it, one `after_create` notification that cannot.
|
|
104
|
-
|
|
105
|
-
```yaml
|
|
106
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
107
|
-
kind: Schema
|
|
108
|
-
metadata:
|
|
109
|
-
name: contact-messages
|
|
110
|
-
spec:
|
|
111
|
-
title: Contact messages
|
|
112
|
-
lifecycle: operational
|
|
113
|
-
schema:
|
|
114
|
-
type: object
|
|
115
|
-
additionalProperties: false
|
|
116
|
-
required: [name, email, message]
|
|
117
|
-
properties:
|
|
118
|
-
name: { type: string, minLength: 1, maxLength: 80 }
|
|
119
|
-
email: { type: string, format: email }
|
|
120
|
-
message: { type: string, minLength: 1, maxLength: 4000 }
|
|
121
|
-
submittedAt: { type: integer, x-mcp-hint: timestamp-ms, x-mantle-bind: now }
|
|
122
|
-
---
|
|
123
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
124
|
-
kind: Procedure
|
|
125
|
-
metadata:
|
|
126
|
-
name: send-contact-message
|
|
127
|
-
spec:
|
|
128
|
-
title: Send contact message
|
|
129
|
-
input:
|
|
130
|
-
type: object
|
|
131
|
-
additionalProperties: false
|
|
132
|
-
required: [name, email, message, botToken]
|
|
133
|
-
properties:
|
|
134
|
-
name: { type: string, minLength: 1, maxLength: 80 }
|
|
135
|
-
email: { type: string, format: email }
|
|
136
|
-
message: { type: string, minLength: 1, maxLength: 4000 }
|
|
137
|
-
botToken: { type: string, minLength: 1 }
|
|
138
|
-
output:
|
|
139
|
-
type: object
|
|
140
|
-
required: [id]
|
|
141
|
-
properties:
|
|
142
|
-
id: { type: string }
|
|
143
|
-
handler: { kind: builtin, op: create, schema: contact-messages }
|
|
144
|
-
---
|
|
145
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
146
|
-
kind: Trigger
|
|
147
|
-
metadata:
|
|
148
|
-
name: contact-http
|
|
149
|
-
spec:
|
|
150
|
-
source: { kind: http, method: POST, path: /api/contact }
|
|
151
|
-
target: { procedure: send-contact-message }
|
|
152
|
-
---
|
|
153
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
154
|
-
kind: Procedure
|
|
155
|
-
metadata:
|
|
156
|
-
name: check-contact-bot
|
|
157
|
-
spec:
|
|
158
|
-
input:
|
|
159
|
-
type: object
|
|
160
|
-
properties:
|
|
161
|
-
botToken: { type: string }
|
|
162
|
-
output: { type: object }
|
|
163
|
-
handler: { kind: ref, ref: check-contact-bot }
|
|
164
|
-
---
|
|
165
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
166
|
-
kind: Trigger
|
|
167
|
-
metadata:
|
|
168
|
-
name: 010-contact-bot-check
|
|
169
|
-
spec:
|
|
170
|
-
source:
|
|
171
|
-
kind: lifecycle
|
|
172
|
-
schema: contact-messages
|
|
173
|
-
on: [before_create]
|
|
174
|
-
errorPolicy: abort
|
|
175
|
-
target: { procedure: check-contact-bot }
|
|
176
|
-
---
|
|
177
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
178
|
-
kind: Procedure
|
|
179
|
-
metadata:
|
|
180
|
-
name: notify-contact-message
|
|
181
|
-
spec:
|
|
182
|
-
input:
|
|
183
|
-
type: object
|
|
184
|
-
properties:
|
|
185
|
-
name: { type: string }
|
|
186
|
-
email: { type: string }
|
|
187
|
-
message: { type: string }
|
|
188
|
-
output: { type: object }
|
|
189
|
-
handler: { kind: ref, ref: notify-contact-message }
|
|
190
|
-
---
|
|
191
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
192
|
-
kind: Trigger
|
|
193
|
-
metadata:
|
|
194
|
-
name: 020-contact-notify
|
|
195
|
-
spec:
|
|
196
|
-
source:
|
|
197
|
-
kind: lifecycle
|
|
198
|
-
schema: contact-messages
|
|
199
|
-
on: [after_create]
|
|
200
|
-
errorPolicy: continue
|
|
201
|
-
target: { procedure: notify-contact-message }
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
What each piece is doing:
|
|
205
|
-
|
|
206
|
-
- `botToken` is declared on the Procedure input but not on the Schema, so it is validated, read by the hook, and never stored.
|
|
207
|
-
- `010-contact-bot-check` runs first because Triggers on the same hook fire alphabetically. Throwing from its handler cancels the insert and the caller receives 409 `LIFECYCLE_HOOK_REJECTED`; nothing is written.
|
|
208
|
-
- `020-contact-notify` runs after the row exists and receives only `entry.data`. A failing mailer is logged, not fatal — the visitor's message is already saved.
|
|
209
|
-
- `submittedAt` is stamped by the runtime, so it is absent from the Procedure input and from Staff MCP authoring tools.
|
|
210
|
-
- Adding `{ kind: mcp, surface: public }` as a fourth Trigger would publish the same Procedure as an agent tool without touching a handler.
|
|
211
|
-
|
|
212
|
-
Register the two `ref` keys in the project's handlers map, then run the check loop from [Project layout and the CLI loop](../start/project-and-cli.md). The complete version with real Turnstile and email handlers is [Intake Turnstile and email hooks](../../examples/cf-primitives-intake-hooks.md). The Builder-safe Manifest without those hooks is [Intake form](../../examples/builtin-intake.md).
|
|
213
|
-
|
|
214
|
-
## Source
|
|
215
|
-
|
|
216
|
-
- [`docs/adr/0001-four-atom-manifest-model.md`](../../../docs/adr/0001-four-atom-manifest-model.md)
|
|
217
|
-
- [`docs/deferred-lifecycle-queues.md`](../../../docs/deferred-lifecycle-queues.md)
|
|
218
|
-
- [`packages/mantle-spec/src/domain/model/ManifestGrammar.ts`](../../../packages/mantle-spec/src/domain/model/ManifestGrammar.ts)
|
|
219
|
-
- [`packages/mantle-runtime/src/domain/service/BuiltinProjector.ts`](../../../packages/mantle-runtime/src/domain/service/BuiltinProjector.ts)
|
|
220
|
-
- [`packages/mantle-runtime/src/infrastructure/http/createMantleRequestHandler.ts`](../../../packages/mantle-runtime/src/infrastructure/http/createMantleRequestHandler.ts)
|
|
221
|
-
- [`docs/skills/develop/SKILL.md`](../../skills/develop/SKILL.md)
|
|
9
|
+
HTTP and MCP Triggers expose a declared Procedure with its existing authorization. Lifecycle and schedule Triggers are rejected by generation. Put side effects in app-owned handlers, and wire scheduled system maintenance with the host's scheduler. See [Procedure](../reference/procedure.md), [Trigger](../reference/trigger.md) and [Store](../guides/typed-queries.md).
|