@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,295 +1,68 @@
|
|
|
1
|
-
|
|
2
|
-
description: The requires grammar — closed auth predicates, guard Procedures, staff roles, HandlerContext, evaluation order and the 401/402/403 mapping.
|
|
3
|
-
---
|
|
4
|
-
# Authorization
|
|
1
|
+
# Authorization requirements
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
## `requires`
|
|
3
|
+
Views and Procedures accept:
|
|
9
4
|
|
|
10
5
|
```yaml
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
- { "ctx.auth.scope": "orders:read" }
|
|
18
|
-
guard:
|
|
19
|
-
procedure: require-active-subscription
|
|
6
|
+
requires:
|
|
7
|
+
auth:
|
|
8
|
+
all:
|
|
9
|
+
- ctx.user
|
|
10
|
+
- ctx.admin
|
|
11
|
+
- { ctx.auth.scope: "exports:read" }
|
|
20
12
|
```
|
|
21
13
|
|
|
22
|
-
|
|
|
23
|
-
|
|
24
|
-
| `
|
|
25
|
-
| `
|
|
26
|
-
| `
|
|
27
|
-
| `requires.guard` | mapping | no | Exactly one key, `procedure`, holding a non-empty Procedure name. |
|
|
28
|
-
|
|
29
|
-
`auth` and `guard` are independent: a target may declare a guard with no static predicates, or predicates with no guard. Shape violations are `INVALID_MANIFEST_ENVELOPE` with a JSON Pointer to the offending key.
|
|
30
|
-
|
|
31
|
-
## Predicates
|
|
14
|
+
| Predicate | Holds when |
|
|
15
|
+
| --- | --- |
|
|
16
|
+
| `ctx.user`, `ctx.auth` | Caller is a verified user |
|
|
17
|
+
| `ctx.admin` | Caller is in the admin layer |
|
|
18
|
+
| `{ ctx.auth.scope: "scope" }` | User scopes include that scope |
|
|
32
19
|
|
|
33
|
-
|
|
20
|
+
Selected REST, MCP and Admin boundaries accept an optional `authorize(target, caller)` callback. `Target`, exported by `@aotter/mantle/contracts`, contains `kind` (`view`, `procedure` or `schema`) and the manifest `name`; Admin generic entry routes also supply `action` (`read`, `create`, `update` or `delete`). The callback runs after credentials and `requires` pass, before execution and row policy. A false result or rejected promise returns `AUTH_DENIED` (HTTP 403); a synchronous exception is an internal error. MCP tool lists and Admin navigation metadata hide denied targets. Omitting the callback preserves existing behavior; direct generated typed functions do not invoke it.
|
|
34
21
|
|
|
35
|
-
|
|
36
|
-
|---|---|---|
|
|
37
|
-
| Signed-in user | `ctx.user` | `ctx.user` is not `null`. A service API key with no user subject fails this. |
|
|
38
|
-
| Verified credential | `ctx.auth` | `ctx.auth` is present, that is, the adapter verified some credential. There is no credential-kind predicate. |
|
|
39
|
-
| Scope | `{ "ctx.auth.scope": "orders:read" }` | `ctx.auth.scopes` contains that exact opaque string. Repeat the predicate under `all` to require several scopes. |
|
|
40
|
-
| Staff role | `{ "ctx.staff": [owner, editor] }` | `ctx.staff` is present and `ctx.staff.role` is one of the listed roles. This is exact membership, not role-or-above. |
|
|
22
|
+
An impersonated session exposes `caller.impersonatedBy`, the real actor’s subject, only on the original branded Caller; applications decide impersonation policy in `authorize(target, caller)`.
|
|
41
23
|
|
|
42
|
-
|
|
43
|
-
|---|---|
|
|
44
|
-
| Predicate is one of the four forms above. | `INVALID_MANIFEST_ENVELOPE` at `/spec/requires/auth/all/<i>` |
|
|
45
|
-
| Object form has exactly one key, `ctx.staff` or `ctx.auth.scope`. | `INVALID_MANIFEST_ENVELOPE` |
|
|
46
|
-
| `ctx.auth.scope` value is a non-empty string. | `INVALID_MANIFEST_ENVELOPE` |
|
|
47
|
-
| `ctx.staff` value is a non-empty array of strings. | `INVALID_MANIFEST_ENVELOPE` |
|
|
48
|
-
| Every `ctx.staff` role is `owner`, `editor` or `contributor`. | `AUTH_PREDICATE_NOT_IN_ENUM` |
|
|
24
|
+
All predicates must hold. Anonymous/system callers satisfy none of these predicates. Without `requires`, the invocation is ungated, while Schema row policy still applies. Role lists such as `{ ctx.admin: [editor] }` are refused: decide per-target roles in application code. Role names match `^[a-z][a-zA-Z0-9_-]{0,62}$`; an invalid name in a verified user's role fails identity resolution and names the role. Better Auth’s admin plugin `adminRoles` (trimmed, default `["admin"]`) and `adminUserIds` determine the admin layer; Mantle has no role setting of its own.
|
|
49
25
|
|
|
50
|
-
|
|
26
|
+
Dynamic `requires.guard` is rejected with `GENERATE_UNSUPPORTED`. Implement custom checks in app-owned handlers before executing queries. Generated TypeScript does not validate arbitrary external input; selected boundaries validate inputs, and direct callers must do so themselves.
|
|
51
27
|
|
|
52
|
-
|
|
28
|
+
Predicate failure is `UNAUTHENTICATED` for a non-user or `AUTH_DENIED` for a user. Scope, TTL and publishing independently limit rows; see [authorization](../concepts/authorization.md).
|
|
53
29
|
|
|
54
|
-
|
|
30
|
+
## User fields
|
|
55
31
|
|
|
56
|
-
|
|
57
|
-
|---|---|---|
|
|
58
|
-
| No `ctx.auth`, no `ctx.user` and no `ctx.staff`. | `UNAUTHENTICATED` | `401` |
|
|
59
|
-
| Authenticated in any of those three ways but a predicate is unsatisfied. | `AUTH_DENIED` | `403` |
|
|
32
|
+
A user field is a value the identity provider verified on the user, such as `region`. It limits rows in two places only:
|
|
60
33
|
|
|
61
|
-
|
|
34
|
+
- A Schema `scope` applies to every SQL relation, Store, REST/MCP and native Admin access: `scope: "region IN auth.user('region')"`. See [Schema](schema.md#field-scope).
|
|
35
|
+
- A View or Procedure `restrict` applies to one target: `restrict: { orders: "region IN auth.user('region')" }`. See [View](view.md#restrict).
|
|
62
36
|
|
|
63
|
-
|
|
37
|
+
Values come from the verified Better Auth user record. Declare stored fields with `input: false` in `user.additionalFields`, or produce derived fields through `customSession`. Session, OAuth and service credentials read roles, bans and stored fields from the same current database user record; customSession-only fields are refused on OAuth/service paths with `AUTH_CONFIGURATION_ERROR`. `input: false` protects only public endpoints. Anyone permitted to update users can change row-access field values through the admin API; control that authority with Better Auth access control (`user:update`, and `user:set-role` for roles). Store `{ all: true }` in a `json` additional field. Pass the generated `userFields` constant as `resolveCaller(request, auth, { fields: userFields })`.
|
|
64
38
|
|
|
65
|
-
|
|
39
|
+
SQL cannot reference caller values: `auth.user()` fails with `USER_REF_SCOPE_ONLY`, and `auth.hasRole()` / `auth.role()` with `AUTH_ROLE_REMOVED`. Names are literals; Better Auth core fields and names beginning `mantle` are reserved.
|
|
66
40
|
|
|
67
|
-
|
|
68
|
-
- It runs through the identical pipeline: its own `requires.auth.all`, its own `input` schema, its handler, its `output` schema.
|
|
69
|
-
- It runs on every call and is never cached.
|
|
70
|
-
- It fails closed. Any non-`ok` guard result is returned to the caller unchanged and the target handler is never invoked.
|
|
41
|
+
Values come from the original frozen Caller, which holds identity in a private WeakMap. Anonymous and copied/unbranded callers have no roles or user fields. Values are validated and frozen: finite numbers, integers when the field scopes an `integer` column; strings of 1–256 UTF-8 bytes without NUL or lone surrogates; arrays of at most 64 items with duplicates removed, only for multi-valued fields. `{ all: true }` is the typed "every value" state of one field; storing it requires a Better Auth additional field of type `json`. Unknown user fields are discarded. A missing or empty value is refused before SQL runs (`UNAUTHENTICATED` for anonymous callers, otherwise `AUTH_DENIED`); it never matches every row. Never mint verified users from request data. Resolve credentials before constructing an identity, and pass the original Caller to generated operations.
|
|
71
42
|
|
|
72
|
-
|
|
73
|
-
|---|---|---|
|
|
74
|
-
| The named Procedure is declared. | `GUARD_PROCEDURE_UNKNOWN` | validate and runtime |
|
|
75
|
-
| A Procedure does not guard itself. | `GUARD_SELF_REFERENCE` | validate and runtime |
|
|
76
|
-
| The guard uses `handler.kind: ref`, not `builtin`. | `GUARD_PROCEDURE_BUILTIN` | validate and runtime |
|
|
77
|
-
| The guard does not itself declare `requires.guard`. Guard chains are one level deep, never more. | `GUARD_CHAIN_NOT_ALLOWED` | validate and runtime |
|
|
43
|
+
## Gateway mode
|
|
78
44
|
|
|
79
|
-
|
|
45
|
+
Selected `rest`, `mcp`, `admin` and `web` boundaries accept `gateway: { tenant: "example" }`. Forward the execution context: `api(request, env, ctx)` from `fetch(request, env, ctx)`. Set gateway mode on every boundary of the application, including web output (`web.fetch(request, env, ctx)` and `web.head(request, env, ctx)`). Only `ctx.props.mantle` supplies identity; absent props are anonymous. Application cookies and bearer tokens are ignored, and the application's auth instance is never loaded. Present `props.mantle` prevents falling back to application credentials. `props.mantle` on an entry without gateway mode fails with `HOST_CONTRACT` (412); the string-returning `web.head` throws this contract error.
|
|
80
46
|
|
|
81
|
-
|
|
47
|
+
The v1 props contain `v: 1`, the configured `tenant`, `layer` (`admin` or `member`), `user` (`id`, optional `role` and declared user fields), `authenticatedAs` (`snapshot` or `fresh`), `credential` (`session` or `oauth`) and `requestId`. `target` and `targetHash` are required for admin callers and optional for members. The boolean `dryRun` is an optional forwarding control. `hostCaller(props, { tenant, fields })` from `@aotter/mantle/host-caller` validates and brands this shape. Generated boundaries supply inferred field types; manually composed boundaries may pass `fields`. Tests call `hostCaller(props, { tenant, fields })` with the same JSON.
|
|
82
48
|
|
|
83
|
-
|
|
49
|
+
Admin-layer callers have kind `host`, subject `host:<id>` and the admin layer. Member-layer callers have kind `user`, subject `<id>` and no admin privilege, regardless of role names. Both retain ordinary scope checks and expose freshness, credential and request id to application code. Admin-layer callers see drafts; member management refuses host-built callers with 403 because gateway-mode applications load no Better Auth instance. Copies lose identity authority.
|
|
84
50
|
|
|
85
|
-
|
|
86
|
-
|---|---|---|
|
|
87
|
-
| `owner` | 3 | Full control. Staff list, role changes, invitations, site settings, developer console. |
|
|
88
|
-
| `editor` | 2 | Publish, unpublish, delete and manage all entries; media uploads and assets; member list. |
|
|
89
|
-
| `contributor` | 1 | Create and edit drafts. Cannot create or edit operational records, and cannot edit an entry that is no longer `draft`. |
|
|
51
|
+
Snapshots may read only: SQL writes, Store/Admin mutations, publishing transitions and ref handlers fail before execution with `STALE_CALLER` (403). Boundary read classification comes from describe’s generated `_meta.readOnly`; generated SQL and Store writes retain their own freshness checks. Session writes keep origin checks. Both layers receive `{ error: { code, field?, target? } }`: 412 for invalid contracts, tenant mismatches or missing/empty required fields (naming the field), 403 for denials, and 400 for malformed bodies; never 401. MCP tool failures use the SDK error result with the same error fields.
|
|
90
52
|
|
|
91
|
-
`
|
|
53
|
+
Pins use [describe](describe.md)'s `_meta.id`: `rest:<METHOD> <path>`, `admin:<METHOD> <path template>`, or the View/Procedure target for MCP and web. The route checks `target` and the generated target hash before execution: mismatches return 412 `TARGET_MISMATCH` or `TARGET_HASH_MISMATCH`. The generated `access-targets.ts` map loads only for gateway requests. Manually composed boundaries can supply an `accessTargets` loader returning the same metadata.
|
|
92
54
|
|
|
93
|
-
|
|
55
|
+
MCP host callers may use `initialize` and `tools/call` of their pinned tool; batches stay refused and `tools/list` returns 403 because the host provides its catalogue.
|
|
94
56
|
|
|
95
|
-
|
|
57
|
+
`dryRun: true` runs target/hash checks, input validation, generated caller checks, `authorize` and freshness, without SQL or side effects. It returns 200 `{ dryRun: true, event }`; MCP carries this result in the SDK tool response. Ref handlers, custom guards, uploads and opaque work return 412 `DRY_RUN_UNSUPPORTED`. Dry runs validate authority and input; they do not verify database state, row existence or OCC conflicts.
|
|
96
58
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
Handlers, guards and predicate evaluation all see the same normalized value.
|
|
59
|
+
Each boundary accepts `onAccess(event)`. Every forwarded request, including malformed contracts and denied requests in either layer, produces one event after its decision. Responses never await the hook; listener failures are swallowed and logged once per listener. Ordinary applications do not invoke it. The event is:
|
|
100
60
|
|
|
101
61
|
```ts
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
readonly credential: "session" | "oauth" | "api-key" | "personal-token";
|
|
107
|
-
readonly credentialId: string | null;
|
|
108
|
-
readonly clientId: string | null;
|
|
109
|
-
readonly scopes: readonly string[];
|
|
110
|
-
};
|
|
111
|
-
readonly env: Env;
|
|
112
|
-
readonly waitUntil?: (p: Promise<unknown>) => void;
|
|
113
|
-
readonly event?: HandlerLifecycleEvent;
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
| Field | Notes |
|
|
118
|
-
|---|---|
|
|
119
|
-
| `user` | `{ id }` of the site-local user row, or `null`. The id is the deployment's own user record, never a platform or upstream-provider subject. |
|
|
120
|
-
| `staff` | Privilege overlay, or `null`. |
|
|
121
|
-
| `auth` | Present only after a credential verified. `credentialId` is an opaque record id or token identifier; `clientId` names the OAuth client when there is one; `scopes` is the granted set. |
|
|
122
|
-
| `env` | Adapter bindings. |
|
|
123
|
-
| `waitUntil` | Platform fire-and-forget bridge, when the adapter has one. |
|
|
124
|
-
| `event` | Populated only when the Procedure runs as a lifecycle hook target. See [Trigger](./trigger.md). |
|
|
125
|
-
|
|
126
|
-
Raw credentials never enter this object: no cookie value, no API key, no bearer token, no refresh token. Resolution precedence on the Cloudflare adapter is the deployment's own credential resolver, then configured OAuth bearer verification, then the cookie session; a recognized-but-invalid credential is rejected outright and never falls back to a valid cookie. See [Authentication](../cloudflare/authentication.md).
|
|
127
|
-
|
|
128
|
-
## Order of evaluation
|
|
129
|
-
|
|
130
|
-
The order is fixed and identical on REST, MCP and in-process invocation.
|
|
131
|
-
|
|
132
|
-
| Step | Procedure | View |
|
|
133
|
-
|---|---|---|
|
|
134
|
-
| 1 | Adapter verifies and normalizes the credential. | Same. |
|
|
135
|
-
| 2 | `requires.auth.all` against the context. | `requires.auth.all` against the context. |
|
|
136
|
-
| 3 | `input` validated and coerced. | `params` validated and coerced. |
|
|
137
|
-
| 4 | Guard invoked with the validated value and the same context. | Guard invoked with the validated params and the same context. |
|
|
138
|
-
| 5 | Handler dispatched. | Query executed. |
|
|
139
|
-
| 6 | `output` validated. | Rows paginated and returned. |
|
|
140
|
-
|
|
141
|
-
Static predicates run before input validation on purpose: an unauthorized caller learns that it is unauthorized, not what the input schema looks like.
|
|
142
|
-
|
|
143
|
-
## Views
|
|
144
|
-
|
|
145
|
-
Two consequences follow from that order.
|
|
146
|
-
|
|
147
|
-
- **Static auth precedes param validation.** A protected View never reports a parameter error to a caller that failed its predicates.
|
|
148
|
-
- **The guard authorizes the query, not the rows.** It sees the validated params and returns pass or fail for the whole call. It cannot rewrite the filter, drop columns or remove rows.
|
|
149
|
-
|
|
150
|
-
Row-level scoping is a separate mechanism, described in [Views](../concepts/views.md): the closed `{ "$ctx.user": "id" }` filter sentinel. The caller never supplies that value, so the same View is safe on REST and on public MCP. Core rejects the sentinel unless the View declares `ctx.user` in `requires.auth.all` and the compared field is the leftmost field of a declared Schema index; a missing identity is `401`, never a dropped filter or a full-table read. The field-level rules are in [View](./view.md#value-forms).
|
|
151
|
-
|
|
152
|
-
## Example
|
|
153
|
-
|
|
154
|
-
```yaml
|
|
155
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
156
|
-
kind: Procedure
|
|
157
|
-
metadata:
|
|
158
|
-
name: require-active-subscription
|
|
159
|
-
spec:
|
|
160
|
-
title: Require an active subscription
|
|
161
|
-
input: { type: object }
|
|
162
|
-
output: { type: object }
|
|
163
|
-
handler: { kind: ref, ref: requireActiveSubscription }
|
|
164
|
-
---
|
|
165
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
166
|
-
kind: Procedure
|
|
167
|
-
metadata:
|
|
168
|
-
name: download-report
|
|
169
|
-
spec:
|
|
170
|
-
title: Download a report
|
|
171
|
-
requires:
|
|
172
|
-
auth:
|
|
173
|
-
all:
|
|
174
|
-
- ctx.user
|
|
175
|
-
- ctx.auth
|
|
176
|
-
- { "ctx.auth.scope": "reports:read" }
|
|
177
|
-
guard: { procedure: require-active-subscription }
|
|
178
|
-
input:
|
|
179
|
-
type: object
|
|
180
|
-
required: [reportId]
|
|
181
|
-
properties:
|
|
182
|
-
reportId: { type: string }
|
|
183
|
-
output:
|
|
184
|
-
type: object
|
|
185
|
-
required: [url]
|
|
186
|
-
properties:
|
|
187
|
-
url: { type: string, format: uri }
|
|
188
|
-
handler: { kind: ref, ref: downloadReport }
|
|
189
|
-
---
|
|
190
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
191
|
-
kind: Trigger
|
|
192
|
-
metadata:
|
|
193
|
-
name: download-report-http
|
|
194
|
-
spec:
|
|
195
|
-
source: { kind: http, method: POST, path: /api/reports/download }
|
|
196
|
-
target: { procedure: download-report }
|
|
197
|
-
---
|
|
198
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
199
|
-
kind: View
|
|
200
|
-
metadata:
|
|
201
|
-
name: my-reports
|
|
202
|
-
spec:
|
|
203
|
-
title: My reports
|
|
204
|
-
surface: public
|
|
205
|
-
from: reports
|
|
206
|
-
requires:
|
|
207
|
-
auth:
|
|
208
|
-
all: [ctx.user]
|
|
209
|
-
guard: { procedure: require-active-subscription }
|
|
210
|
-
filter:
|
|
211
|
-
and:
|
|
212
|
-
- { eq: { field: status, value: published } }
|
|
213
|
-
- { eq: { field: ownerId, value: { "$ctx.user": id } } }
|
|
214
|
-
fields: [title, publishedAt]
|
|
215
|
-
orderBy: [{ field: publishedAt, direction: desc }]
|
|
216
|
-
limit: 50
|
|
62
|
+
{ v: 1, requestId, target, targetHash,
|
|
63
|
+
caller: { kind, subject, layer },
|
|
64
|
+
outcome: "allow" | "deny" | "error", reason?, field?,
|
|
65
|
+
dryRun }
|
|
217
66
|
```
|
|
218
67
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
Because `my-reports` is guarded and binds `$ctx.user`, it must not declare `View.spec.cache`. Shared View caching is reserved for caller-independent anonymous reads; `VIEW_CACHE_INVALID` rejects guarded or identity-bound combinations.
|
|
222
|
-
|
|
223
|
-
```ts
|
|
224
|
-
import { DiagnosticError, runtimeDiagnostic } from "@aotter/mantle/spec";
|
|
225
|
-
import type { HandlerContext } from "@aotter/mantle/runtime";
|
|
226
|
-
|
|
227
|
-
export const requireActiveSubscription = async (
|
|
228
|
-
_input: unknown,
|
|
229
|
-
ctx: HandlerContext<{ DB: D1Database }>,
|
|
230
|
-
) => {
|
|
231
|
-
const active = await ctx.env.DB
|
|
232
|
-
.prepare("SELECT 1 FROM site_memberships WHERE user_id = ? AND state = 'active' LIMIT 1")
|
|
233
|
-
.bind(ctx.user!.id)
|
|
234
|
-
.first();
|
|
235
|
-
if (active) return {};
|
|
236
|
-
throw new DiagnosticError(
|
|
237
|
-
runtimeDiagnostic({
|
|
238
|
-
code: "ENTITLEMENT_REQUIRED",
|
|
239
|
-
severity: "error",
|
|
240
|
-
path: `site:membership/${ctx.user!.id}`,
|
|
241
|
-
message: "An active subscription is required.",
|
|
242
|
-
}),
|
|
243
|
-
);
|
|
244
|
-
};
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
`site_memberships` is deployment-owned. Core creates no credential, entitlement or billing tables and reads no payment-provider state.
|
|
248
|
-
|
|
249
|
-
## OpenAPI projection
|
|
250
|
-
|
|
251
|
-
`mantle emit-openapi` reflects authorization into the emitted OpenAPI 3.1 document. Only schemes the deployment actually accepts are configured, and only those become alternatives.
|
|
252
|
-
|
|
253
|
-
| Manifest | OpenAPI |
|
|
254
|
-
|---|---|
|
|
255
|
-
| Any `requires.auth.all` predicate | `security` alternatives drawn from the configured `sessionCookie`, `oauthBearer`, `apiKey` and `personalToken` schemes, plus `x-mantle-auth-predicates`, a `401` response and a `403` response. |
|
|
256
|
-
| Repeated `{ "ctx.auth.scope": … }` | OAuth scopes on the `oauthBearer` alternative, plus `x-mantle-required-scopes`. |
|
|
257
|
-
| `requires.guard.procedure` | `x-mantle-guard-procedure` and a `402` response. |
|
|
258
|
-
| No `requires` | No `security` requirement and no auth responses. |
|
|
259
|
-
|
|
260
|
-
Cookie sessions are emitted as cookies, never relabelled as bearer tokens. A protected target with no configured security scheme is an emission error, not a silently unprotected operation. MCP is out of scope for the emitter; required scopes and guard behaviour reach agents through the standard Tool description, and every `tools/call` re-runs the predicates and the guard. Discovery is never the enforcement boundary — see [MCP and agents](../concepts/mcp-and-agents.md).
|
|
261
|
-
|
|
262
|
-
Configure the accepted schemes through the public API:
|
|
263
|
-
|
|
264
|
-
```ts
|
|
265
|
-
import { EmitOpenapiUseCase } from "@aotter/mantle/spec";
|
|
266
|
-
|
|
267
|
-
const { document } = EmitOpenapiUseCase.run({
|
|
268
|
-
linked, // successful linkManifestSet result
|
|
269
|
-
title: "Site API",
|
|
270
|
-
version: "1.0.0",
|
|
271
|
-
security: {
|
|
272
|
-
sessionCookie: false,
|
|
273
|
-
oauthBearer: {
|
|
274
|
-
openIdConnectUrl:
|
|
275
|
-
"https://platform.example.com/api/auth/.well-known/openid-configuration",
|
|
276
|
-
},
|
|
277
|
-
apiKey: { in: "header", name: "X-API-Key" },
|
|
278
|
-
personalToken: { bearerFormat: "PAT" },
|
|
279
|
-
},
|
|
280
|
-
});
|
|
281
|
-
```
|
|
282
|
-
|
|
283
|
-
## Source
|
|
284
|
-
|
|
285
|
-
- [`packages/mantle-spec/src/domain/model/ManifestGrammar.ts`](../../../packages/mantle-spec/src/domain/model/ManifestGrammar.ts)
|
|
286
|
-
- [`packages/mantle-spec/src/domain/service/ManifestParser.ts`](../../../packages/mantle-spec/src/domain/service/ManifestParser.ts)
|
|
287
|
-
- [`packages/mantle-spec/src/domain/service/ManifestGraphValidator.ts`](../../../packages/mantle-spec/src/domain/service/ManifestGraphValidator.ts)
|
|
288
|
-
- [`packages/mantle-spec/src/domain/service/StaffRoleHierarchy.ts`](../../../packages/mantle-spec/src/domain/service/StaffRoleHierarchy.ts)
|
|
289
|
-
- [`packages/mantle-spec/src/usecase/EmitOpenapiUseCase.ts`](../../../packages/mantle-spec/src/usecase/EmitOpenapiUseCase.ts)
|
|
290
|
-
- [`packages/mantle-runtime/src/domain/model/HandlerContext.ts`](../../../packages/mantle-runtime/src/domain/model/HandlerContext.ts)
|
|
291
|
-
- [`packages/mantle-runtime/src/domain/service/AuthPredicateEvaluator.ts`](../../../packages/mantle-runtime/src/domain/service/AuthPredicateEvaluator.ts)
|
|
292
|
-
- [`packages/mantle-runtime/src/usecase/procedure/InvokeProcedureUseCase.ts`](../../../packages/mantle-runtime/src/usecase/procedure/InvokeProcedureUseCase.ts)
|
|
293
|
-
- [`packages/mantle-runtime/src/usecase/view/ExecuteViewUseCase.ts`](../../../packages/mantle-runtime/src/usecase/view/ExecuteViewUseCase.ts)
|
|
294
|
-
- [`packages/mantle-admin/src/mountMantleAdmin.ts`](../../../packages/mantle-admin/src/mountMantleAdmin.ts)
|
|
295
|
-
- [`packages/adapters/cloudflare/src/mount/mountMcp.ts`](../../../packages/adapters/cloudflare/src/mount/mountMcp.ts)
|
|
68
|
+
`reason` is the error code. A successful dry run returns the same event the hook receives.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Describe
|
|
2
|
+
|
|
3
|
+
`mantle describe <target> <manifest>...` compiles manifests and prints JSON.
|
|
4
|
+
An explicit target is required; use the generation target because hashes
|
|
5
|
+
include the dialect. The command writes no project files. `--diff <old.json>` prints a JSON
|
|
6
|
+
array of changes against a saved report.
|
|
7
|
+
|
|
8
|
+
`describeApp(plan)` and `diffApp(a, b)` are exported by
|
|
9
|
+
`@aotter/mantle/describe`. The `AppDescription` TypeScript type is the contract.
|
|
10
|
+
`targetHash(plan, id)` is also exported by `@aotter/mantle/target-hash`.
|
|
11
|
+
These exports use no Node APIs and load no SQL parser.
|
|
12
|
+
|
|
13
|
+
The schemaVersion 1 report contains:
|
|
14
|
+
|
|
15
|
+
- `access`: `plan.access.userFields`, mapping declared user fields to their
|
|
16
|
+
type, multiplicity and optional enum.
|
|
17
|
+
- `targets`: MCP Tool-shaped objects with `name`, `title`, `description`,
|
|
18
|
+
`inputSchema`, `annotations` and `_meta`. View and Procedure names follow
|
|
19
|
+
MCP naming. Route inputs are plain objects with a name selector for known
|
|
20
|
+
dispatcher variants; their `variants` retain the selected input schemas.
|
|
21
|
+
|
|
22
|
+
Each target’s `_meta` contains:
|
|
23
|
+
|
|
24
|
+
- `id`: `view:<name>`, `procedure:<name>`, `rest:<METHOD> <path>` or
|
|
25
|
+
`admin:<METHOD> <path template>`. Parameters use `:name`; Admin paths are
|
|
26
|
+
relative to the API base. Publishing ids use `procedure:<schema>.<verb>`;
|
|
27
|
+
media tool ids use `admin:tool:<name>`.
|
|
28
|
+
- `targetHash`: a hash of behavior, inputs, requirements, restrictions,
|
|
29
|
+
related Schema definitions, surfaces, Triggers and reachable hooks.
|
|
30
|
+
Optional lowering caches do not affect it. Ref registration keys are
|
|
31
|
+
included; application-owned handler implementations are not.
|
|
32
|
+
- `scope` and `restrict`: per-Schema owner and user-field terms. Owner terms
|
|
33
|
+
use `owner`; user-field terms name their `column`, `field` and `type`.
|
|
34
|
+
- `readOnly`: true only when all reachable statements are reads. Ref handlers
|
|
35
|
+
and routes without known dependencies are false.
|
|
36
|
+
- `trustedOnly`, `opaque`, `unscopedReads`: trusted-only execution, ref-handler
|
|
37
|
+
opacity and reads of Schemas without row scope. Opaque code conservatively
|
|
38
|
+
includes every Schema available to its Store.
|
|
39
|
+
- `surfaces` and `triggers`: every declared exposure and each Trigger’s id
|
|
40
|
+
and source. Views include `admin` for developer previews.
|
|
41
|
+
- `requires`: conjunctive predicates in `all` and an optional `guard` name.
|
|
42
|
+
Admin-only targets include the admin gate.
|
|
43
|
+
- `variants`: each selectable target’s id, input schema, requirements, flags
|
|
44
|
+
and row policies. Route restrictions contain terms common to all variants.
|
|
45
|
+
|
|
46
|
+
Descriptions contain no SQL or rows. They describe declarations; application
|
|
47
|
+
router additions and optional module mounting remain application-owned.
|
|
48
|
+
|
|
49
|
+
Diff records contain `id`, `field`, `direction` and optional `before`/`after`.
|
|
50
|
+
Removing a scope or restrict term widens access; adding one narrows it.
|
|
51
|
+
Reading another Schema, dropping requirements, adding surfaces or Triggers,
|
|
52
|
+
removing `readOnly` or `trustedOnly`, or enabling `opaque` or `unscopedReads`
|
|
53
|
+
widens access. Variants are compared separately. Adding a target widens;
|
|
54
|
+
removing one narrows. Every input schema change is `changed`, as are other
|
|
55
|
+
behavior changes. Directions describe individual changes, not an overall
|
|
56
|
+
proof when several fields change.
|