@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
package/docs/adapter-guide.md
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
# Adapter implementation guide
|
|
2
|
-
|
|
3
|
-
This guide is the fresh-developer entry point for implementing a new mantle platform adapter.
|
|
4
|
-
|
|
5
|
-
Read this with [ADR-0019](adr/0019-sealed-manifest-runtime-pipeline.md). The source of truth for TypeScript shapes is `packages/mantle-runtime/src/domain/port/`.
|
|
6
|
-
|
|
7
|
-
Adapter packages live under `packages/adapters/<platform>/` using a plural `adapters` bucket. The npm package names stay unchanged, for example `@aotter/mantle-cloudflare`. Keep adapters in this monorepo until the runtime/spec API is stable enough that coordinated releases across separate repositories would not create version skew for consumers.
|
|
8
|
-
|
|
9
|
-
## Required storage boundary
|
|
10
|
-
|
|
11
|
-
A storage adapter prepares one `RuntimePlan` into semantic ports:
|
|
12
|
-
|
|
13
|
-
| Contract | Source | Cloudflare example |
|
|
14
|
-
|---|---|---|
|
|
15
|
-
| `MantleStorageAdapter` / `PreparedMantleStorage` | `packages/mantle-runtime/src/domain/port/MantleStorageAdapter.ts` | `SqliteMantleStorageAdapter` over `D1DatabaseDriver` |
|
|
16
|
-
| `EntryRepository & EntryReader` | Existing semantic content ports | `DatabaseEntryRepository` supplied by the SQLite adapter |
|
|
17
|
-
| `ViewQueryExecutor` | `packages/mantle-runtime/src/domain/port/ViewQueryExecutor.ts` | `SqliteViewQueryExecutor` |
|
|
18
|
-
|
|
19
|
-
`DatabaseDriver` is only the reusable SQLite/D1 implementation seam. A
|
|
20
|
-
PostgreSQL, MongoDB, or application-owned-table adapter implements the semantic
|
|
21
|
-
ports directly; it does not emulate D1 and needs no mapping DSL. Platform types
|
|
22
|
-
such as `D1Database`, Postgres pools, and Mongo clients remain in adapter code.
|
|
23
|
-
|
|
24
|
-
## Optional capabilities
|
|
25
|
-
|
|
26
|
-
Optional ports are enabled only when a feature needs them:
|
|
27
|
-
|
|
28
|
-
| Contract | Source | Required when |
|
|
29
|
-
|---|---|---|
|
|
30
|
-
| `MediaStorage` | `packages/mantle-runtime/src/domain/port/MediaStorage.ts` | The adapter exposes admin/MCP media upload flows. |
|
|
31
|
-
| `DeferredHookDispatcher` | `packages/mantle-runtime/src/domain/port/DeferredHookDispatcher.ts` | The adapter wants at-least-once queue delivery for `after_*` lifecycle hooks. |
|
|
32
|
-
|
|
33
|
-
Test seams such as `Clock` and `IdGenerator` are injectable through `createMantleRuntime`, but normal adapters do not need custom implementations.
|
|
34
|
-
|
|
35
|
-
Deferred delivery is an optional, versioned wire contract. Queue acceptance is
|
|
36
|
-
not atomic with the entry write; adapters must preserve the supplied event id,
|
|
37
|
-
validate untrusted messages before dereferencing them, surface handler failures
|
|
38
|
-
to their retry mechanism, and document poison-message/DLQ behavior. See
|
|
39
|
-
[Deferred lifecycle hooks on Cloudflare Queues](deferred-lifecycle-queues.md)
|
|
40
|
-
for the reference implementation and exact guarantees.
|
|
41
|
-
|
|
42
|
-
## Storage preparation
|
|
43
|
-
|
|
44
|
-
Compile before deployment preparation, then pass only the sealed plan:
|
|
45
|
-
|
|
46
|
-
```ts
|
|
47
|
-
import {
|
|
48
|
-
bootMantleRuntime,
|
|
49
|
-
SqliteMantleStorageAdapter,
|
|
50
|
-
} from "@aotter/mantle-runtime";
|
|
51
|
-
|
|
52
|
-
const storage = new SqliteMantleStorageAdapter(db, siteDefaults);
|
|
53
|
-
const runtime = await bootMantleRuntime({
|
|
54
|
-
plan,
|
|
55
|
-
storage,
|
|
56
|
-
handlers,
|
|
57
|
-
ports,
|
|
58
|
-
deployment: {
|
|
59
|
-
reservedHttpPathPrefixes: selectedCapabilities.flatMap(
|
|
60
|
-
(capability) => capability.reservedHttpPathPrefixes,
|
|
61
|
-
),
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
`bootMantleRuntime` performs one attempt and derives Procedure readiness from
|
|
67
|
-
the supplied handlers. The platform adapter remains responsible for lazy boot,
|
|
68
|
-
promise caching, retry policy, and teardown.
|
|
69
|
-
|
|
70
|
-
Hosts that need work between preparation and binding may keep the same stages
|
|
71
|
-
public and explicit:
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
const prepared = await prepareDeployment(plan, storage, {
|
|
75
|
-
handlerNames: Object.keys(handlers ?? {}),
|
|
76
|
-
});
|
|
77
|
-
const runtime = createMantleRuntime({ prepared, handlers, ports });
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
The prepared revision carries its exact plan, but exposes both `plan` and
|
|
81
|
-
`storage`; it seals the pairing invariant rather than hiding low-level host
|
|
82
|
-
capabilities. Omit `handlerNames` only for a read-only embedding that never
|
|
83
|
-
dispatches Procedures.
|
|
84
|
-
|
|
85
|
-
The official SQLite adapter runs canonical migrations, materializes one native
|
|
86
|
-
table per Schema, prepares indexes and Views, and skips mutation for an
|
|
87
|
-
unchanged storage revision. A
|
|
88
|
-
custom adapter owns its own preparation and returns application-owned semantic
|
|
89
|
-
ports. Unsupported native View dialects fail before the adapter mutates state.
|
|
90
|
-
|
|
91
|
-
### Bun embedding
|
|
92
|
-
|
|
93
|
-
> **Experimental.** The Bun and Vercel adapters may change in a minor
|
|
94
|
-
> release. They cover public Views and HTTP Triggers; the host owns
|
|
95
|
-
> authentication and CSRF, and Auth, Admin and MCP are Cloudflare-only today.
|
|
96
|
-
> Cloudflare is the supported host.
|
|
97
|
-
|
|
98
|
-
`@aotter/mantle-bun` is the minimal SQLite reference: pass an application-owned
|
|
99
|
-
`bun:sqlite` `Database` and a compiled `RuntimePlan` to `createBunMantle()`.
|
|
100
|
-
Its `handle()` returns `null` for sibling routes and a Web-standard `Response`
|
|
101
|
-
for manifest-declared public Views and HTTP Triggers. The host owns
|
|
102
|
-
`Bun.serve`, database shutdown, authentication, and CSRF policy; the adapter
|
|
103
|
-
prepares the semantic revision once and retries only after failed preparation.
|
|
104
|
-
|
|
105
|
-
### Vercel Functions embedding
|
|
106
|
-
|
|
107
|
-
`@aotter/mantle-vercel` accepts a compiled plan plus any application-owned
|
|
108
|
-
`MantleStorageAdapter` and reuses the same public View/HTTP Trigger transport as
|
|
109
|
-
Bun. It maps deferred work to Vercel Functions `waitUntil` and otherwise leaves
|
|
110
|
-
the Web Handler, auth/CSRF, and route composition to the application. The
|
|
111
|
-
optional `/libsql` subpath adapts a caller-owned remote Turso/libSQL client to
|
|
112
|
-
the canonical SQLite chain; the default entry has no database-vendor policy.
|
|
113
|
-
Vercel's read-only filesystem and writable `/tmp` are never durable state.
|
|
114
|
-
|
|
115
|
-
### Browser IndexedDB embedding
|
|
116
|
-
|
|
117
|
-
`@aotter/mantle-indexeddb` implements the same required semantic storage ports
|
|
118
|
-
over one application-owned IndexedDB database. It keeps browser globals out of
|
|
119
|
-
Runtime Core, supports declarative Views with a documented O(n) collection
|
|
120
|
-
scan, and exposes `deleteDatabase()` only on the concrete adapter. The host owns
|
|
121
|
-
database naming, `navigator.storage` persistence requests, active-runtime
|
|
122
|
-
selection, UI invalidation, and any remote synchronization.
|
|
123
|
-
|
|
124
|
-
## HTTP and MCP surfaces
|
|
125
|
-
|
|
126
|
-
The runtime is a library, not an HTTP server. A new adapter must mount equivalent framework routes:
|
|
127
|
-
|
|
128
|
-
| Surface | Adapter responsibility | Cloudflare reference |
|
|
129
|
-
|---|---|---|
|
|
130
|
-
| Runtime HTTP endpoints | Route HTTP Triggers and public View REST endpoints into runtime use cases. | `packages/adapters/cloudflare/src/mount/mountRuntimeEndpoints.ts` |
|
|
131
|
-
| Optional Admin | Supply session/request context and assets to `mantle-admin`; mount only when selected. | `packages/adapters/cloudflare/src/mount/mountAdmin.ts` |
|
|
132
|
-
| Auth endpoints | Own sign-in/session/OAuth metadata through the adapter's Better Auth implementation selected by Admin/OAuth surfaces. | `packages/adapters/cloudflare/src/auth/createAuth.ts` |
|
|
133
|
-
| MCP endpoints | Mount `/mcp/staff` and `/mcp` behind one canonical protected resource. The adapter verifies Better Auth JWTs, normalizes the caller, re-reads the staff D1 role, then dispatches JSON-RPC. | `packages/adapters/cloudflare/src/mount/mountMcp.ts`, `auth/createAuth.ts` |
|
|
134
|
-
|
|
135
|
-
Auth is not a runtime port. Per [ADR-0014](adr/0014-auth-better-auth-and-multi-tenant-mcp.md), the adapter owns Better Auth wiring and passes authenticated user/staff context into runtime dispatchers. Procedure handlers receive that data through `HandlerContext` in `packages/mantle-runtime/src/domain/model/HandlerContext.ts`.
|
|
136
|
-
|
|
137
|
-
The adapter must also normalize verified credential metadata into
|
|
138
|
-
`HandlerContext.auth` (`credential`, opaque `credentialId`, optional
|
|
139
|
-
`clientId`, scopes). Platform-native session/OAuth verification stays in the
|
|
140
|
-
adapter. A narrow adapter extension seam may let consumer code verify its own
|
|
141
|
-
API-key or personal-token formats, but credential storage/issuance must not
|
|
142
|
-
become a runtime port. The Cloudflare reference is
|
|
143
|
-
`mount/resolveCaller.ts`; consumer usage is documented in
|
|
144
|
-
[API and MCP authorization](examples/cf-primitives-guarded-api.md).
|
|
145
|
-
|
|
146
|
-
Minimum HTTP behavior for a full adapter:
|
|
147
|
-
|
|
148
|
-
- Route manifest HTTP Triggers to `runtime.invokeProcedure`.
|
|
149
|
-
- Route `GET /api/views/<name>` to `runtime.executeView`.
|
|
150
|
-
- Mount admin content APIs with session/role checks before calling runtime content use cases.
|
|
151
|
-
- Serve selected Admin SPA assets through `AdminAssetServer`, with an SPA catchall for client-side routes.
|
|
152
|
-
- Mount public render routes and markdown mirrors when the application exposes public pages.
|
|
153
|
-
- Translate runtime diagnostics and validation failures into stable HTTP JSON responses instead of throwing raw errors.
|
|
154
|
-
- Evaluate target auth and dynamic guards through the runtime use cases; do
|
|
155
|
-
not duplicate guard logic in HTTP handlers.
|
|
156
|
-
|
|
157
|
-
For the Cloudflare adapter, public rendering requires three matching consumer
|
|
158
|
-
inputs: `mountPublicRoutes(...)` route declarations, a `TemplateRegistry`
|
|
159
|
-
passed through `MantleCloudflareConfig.templates`, and a `publicPathResolver`
|
|
160
|
-
passed through `MantleCloudflareConfig.publicPathResolver`. Omitting public routes is valid for a headless
|
|
161
|
-
consumer; mounting every Schema automatically is not, because some collections
|
|
162
|
-
are private even when they contain a slug.
|
|
163
|
-
|
|
164
|
-
`TemplateRegistry` and `createPublicPathResolver` come from
|
|
165
|
-
`@aotter/mantle-web`. Other adapters can call `createMantleWeb(runtime)` and map
|
|
166
|
-
its document operations into their own routing and cache conventions.
|
|
167
|
-
|
|
168
|
-
### HTTP cache contract
|
|
169
|
-
|
|
170
|
-
Keep responses private by default. For Cloudflare, apply the final policy after
|
|
171
|
-
all routes and preserve only explicit anonymous public opt-in. Follow the
|
|
172
|
-
[public cache contract](handbook/cloudflare/public-web.md#cache-contract) and the
|
|
173
|
-
[performance harness](performance-harness.md#cache-contract) for verification.
|
|
174
|
-
|
|
175
|
-
Minimum auth/MCP behavior:
|
|
176
|
-
|
|
177
|
-
- Provide Better Auth-compatible sign-in/session routes for the platform.
|
|
178
|
-
- Validate `/mcp/staff` requests with the staff D1 admin role (`owner`/`editor`/`contributor`).
|
|
179
|
-
- Validate `/mcp` requests with any authenticated session (D1 role check is surface-driven, not OAuth-scope-driven — claude.ai rejects colon-shaped scopes).
|
|
180
|
-
- Advertise a single non-colon scope (default `["mcp"]`) in `scopes_supported`. Per-surface enforcement happens server-side in the apiHandler.
|
|
181
|
-
- Build `McpAuthContext` from the validated session and pass it to `McpJsonRpcDispatcher`.
|
|
182
|
-
- Build Procedure/View `HandlerContext` with `user`, live `staff`, normalized
|
|
183
|
-
`auth`, adapter `env`, and optional `waitUntil`.
|
|
184
|
-
- Re-read mutable staff role for each protected REST/MCP invocation. Token or
|
|
185
|
-
consent-time role snapshots are not an authorization boundary.
|
|
186
|
-
- Keep `tools/list` filtering as UX only; route every `tools/call` through the
|
|
187
|
-
same auth evaluator and guard runner used by REST.
|
|
188
|
-
|
|
189
|
-
## Static assets
|
|
190
|
-
|
|
191
|
-
`AdminAssetServer` belongs to optional `@aotter/mantle-admin`. Headless Core
|
|
192
|
-
storage preparation and binding do not accept or require a static asset port.
|
|
193
|
-
|
|
194
|
-
## Implementation checklist
|
|
195
|
-
|
|
196
|
-
- [ ] Run `runStorageConformance` from `@aotter/mantle-runtime/testing/storage`
|
|
197
|
-
against a disposable prepared-storage factory. See the
|
|
198
|
-
[Runtime conformance guide](../packages/mantle-runtime/README.md#storage-adapter-conformance)
|
|
199
|
-
for coverage, cleanup, locale setup, and remaining adapter-specific tests.
|
|
200
|
-
- [ ] Implement `MantleStorageAdapter` returning existing semantic ports, or reuse `SqliteMantleStorageAdapter` with an already-owned handle.
|
|
201
|
-
- [ ] Call `bootMantleRuntime()` once per semantic revision, or explicitly prepare before binding.
|
|
202
|
-
- [ ] Mount HTTP Trigger and View REST surfaces.
|
|
203
|
-
- [ ] Mount admin/public render routes and admin SPA assets.
|
|
204
|
-
- [ ] Provide adapter-owned Better Auth wiring and session helpers.
|
|
205
|
-
- [ ] Normalize session/OAuth and any consumer credential seam into
|
|
206
|
-
`HandlerContext.auth`; never put raw credentials in runtime context.
|
|
207
|
-
- [ ] Mount `/mcp/staff` and `/mcp` behind one resource-bound token verifier. Enforce the live staff role inside the apiHandler.
|
|
208
|
-
- [ ] Preserve the HTTP cache contract: private by default; explicit anonymous 200 `GET`/`HEAD` public opt-in only.
|
|
209
|
-
- [ ] Prove one guarded target has identical REST/MCP outcomes, including
|
|
210
|
-
mutable revocation on the next call.
|
|
211
|
-
- [ ] Add optional `MediaStorage` or `DeferredHookDispatcher` only when the adapter supports those features.
|
|
212
|
-
- [ ] For deferred hooks, document at-least-once delivery, idempotency,
|
|
213
|
-
message limits, retries/DLQ, and the non-transactional write-to-enqueue gap.
|
|
214
|
-
- [ ] Verify the runtime package still has no platform-specific imports.
|
|
215
|
-
|
|
216
|
-
## Current non-goals
|
|
217
|
-
|
|
218
|
-
- Do not add `SessionRepository`, `OAuthVerifier`, `UserRepository`, or `StaffRepository` runtime ports. Those were pre-ADR-0014 concepts and are not part of the current adapter contract.
|
|
219
|
-
- Do not add API-key, personal-token, transaction, billing, or entitlement
|
|
220
|
-
repositories to Core. They are consumer state behind the adapter resolver
|
|
221
|
-
and guard Procedure.
|
|
222
|
-
- Do not generalize `DatabaseDriver` for PostgreSQL/MongoDB or add a mapping DSL. Implement semantic ports; SQLite/D1 alone reuse the canonical SQL chain.
|
|
@@ -1,440 +0,0 @@
|
|
|
1
|
-
# ADR-0001: 4-atom YAML manifest model under `cms.mantle.aotter.net/v1`
|
|
2
|
-
|
|
3
|
-
**Status:** Accepted for the four-atom grammar and multi-document YAML;
|
|
4
|
-
the fixed `site.yaml` file contract is superseded by ADR-0019.
|
|
5
|
-
|
|
6
|
-
**Date**: 2026-04-30 (POC origin); last amended 2026-08-16
|
|
7
|
-
|
|
8
|
-
**Deciders**: phsu
|
|
9
|
-
|
|
10
|
-
**Related**: ADR-0002 (closed enums for bindings),
|
|
11
|
-
[ADR-0019](0019-sealed-manifest-runtime-pipeline.md) (caller-owned source boundary)
|
|
12
|
-
|
|
13
|
-
> **2026-08-16 amendment:** the four atoms and multi-document YAML remain
|
|
14
|
-
> normative. Core no longer assigns source file names: its parser accepts
|
|
15
|
-
> caller-owned source IDs, and its CLI reads immediate `.yaml` / `.yml` files
|
|
16
|
-
> in lexicographic order. `manifests/site.yaml` remains only a starter
|
|
17
|
-
> convention. Fixed-file statements below are retained as decision history.
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Context
|
|
22
|
-
|
|
23
|
-
The SDK's surface area to consumers is YAML manifests. The
|
|
24
|
-
question is: what set of resource kinds does that surface
|
|
25
|
-
expose? Too few and authors find themselves cramming concepts
|
|
26
|
-
into the wrong atom; too many and consumers face a long enum of
|
|
27
|
-
"what kind do I write today" with overlapping semantics.
|
|
28
|
-
|
|
29
|
-
Earlier iterations of this CMS experimented with 11 domain-shaped
|
|
30
|
-
kinds (`ContentSchema`, `ContentView`, `Form`, `Membership`,
|
|
31
|
-
`Email`, `Webhook`, `Workflow`, `ScheduledJob`, etc.). Two
|
|
32
|
-
problems surfaced:
|
|
33
|
-
|
|
34
|
-
1. **Authors couldn't find the right atom for a new feature.**
|
|
35
|
-
"Is a contact form a `Form`, a `Workflow`, an `Email`, or all
|
|
36
|
-
three?" Real features cross domain boundaries.
|
|
37
|
-
2. **Atoms drifted toward overlap.** A `Form` developed an
|
|
38
|
-
`email:` block; a `Webhook` developed a `validation:` block;
|
|
39
|
-
each new kind grew to subsume neighbors.
|
|
40
|
-
|
|
41
|
-
A multi-round design experiment (6 rounds + R6.5 falsification +
|
|
42
|
-
R7 reframing, run as a 4-agent debate over a blog feature
|
|
43
|
-
progression: like button → threaded comments → private posts →
|
|
44
|
-
rate-limited writes → cross-Schema invariants) reduced the kind
|
|
45
|
-
count to 4 and tested those 4 against 6 increasingly demanding
|
|
46
|
-
features without needing a 5th.
|
|
47
|
-
|
|
48
|
-
The relevant history that this ADR records (so future readers
|
|
49
|
-
don't re-litigate it):
|
|
50
|
-
|
|
51
|
-
- **R0 — "atoms ≡ PG primitives" claim**: the experiment opened
|
|
52
|
-
with the heuristic "4 kinds because Postgres has 4
|
|
53
|
-
application-developer primitives." Held for 6 rounds without
|
|
54
|
-
challenge.
|
|
55
|
-
- **R6.5 — falsification round**: an agent proposed cutting to
|
|
56
|
-
3 atoms by folding `Procedure` into `Schema.operations` (PG
|
|
57
|
-
functions attach to schemas in pg_proc). 92→58 LOC reduction
|
|
58
|
-
in the worked example by adding a default-CRUD shortcut.
|
|
59
|
-
Accepted by the round's judge.
|
|
60
|
-
- **R7 — user reframing**: reverted to 4 atoms, but for a
|
|
61
|
-
different reason than R0. The right axis isn't "PG
|
|
62
|
-
primitive"; it's "contract vs implementation × state vs
|
|
63
|
-
event":
|
|
64
|
-
|
|
65
|
-
| | request | event |
|
|
66
|
-
|---|---|---|
|
|
67
|
-
| external API | View (read) / write-API atom | (empty in v0.1) |
|
|
68
|
-
| internal | (Schema's writes are via the write-API atom) | Trigger (reaction) / Schema (state) |
|
|
69
|
-
|
|
70
|
-
**Design lesson** (worth surfacing because it shaped both this
|
|
71
|
-
ADR and the multi-doc YAML decision below): in multi-round
|
|
72
|
-
agent-team debates, decisions ratified in early rounds tend to
|
|
73
|
-
inherit forward through later rounds even when the local
|
|
74
|
-
conditions that justified them have changed. The orchestrator
|
|
75
|
-
must re-test prior naming / structural decisions whenever the
|
|
76
|
-
spec surface materially shifts; agent-team consensus is a strong
|
|
77
|
-
signal but not authoritative.
|
|
78
|
-
|
|
79
|
-
## Decision
|
|
80
|
-
|
|
81
|
-
The SDK exposes exactly **four declarative resource kinds** under
|
|
82
|
-
the `cms.mantle.aotter.net/v1` API group:
|
|
83
|
-
|
|
84
|
-
| Atom | Postgres equivalent | Externally exposed by itself? | Has user code? |
|
|
85
|
-
|---|---|---|---|
|
|
86
|
-
| `Schema` | `CREATE TABLE` | no | no |
|
|
87
|
-
| `View` | `CREATE VIEW` | yes (auto-mounted at `GET /api/views/<name>`; see ADR-0012) | no |
|
|
88
|
-
| `Procedure` | `CREATE FUNCTION ... LANGUAGE plpgsql` | **no** (transport-agnostic; needs a Trigger to bind) | **yes — handler ref to consumer's TS** |
|
|
89
|
-
| `Trigger` | `CREATE TRIGGER` + route/tool binding | yes (the binding atom) | no |
|
|
90
|
-
|
|
91
|
-
### Path A: Trigger does all binding
|
|
92
|
-
|
|
93
|
-
A Procedure is **not externally exposed by itself**. To make it
|
|
94
|
-
callable over HTTP / MCP / lifecycle, declare a
|
|
95
|
-
`Trigger` whose `target.procedure` points at it. The same
|
|
96
|
-
Procedure can be bound by multiple Triggers (HTTP + MCP,
|
|
97
|
-
all sharing one handler).
|
|
98
|
-
|
|
99
|
-
This is "Path A" relative to an alternative considered (and
|
|
100
|
-
rejected — see below) where Procedures carried an inline
|
|
101
|
-
`expose:` block.
|
|
102
|
-
|
|
103
|
-
### PG-1:1 mapping is the primary onboarding pitch
|
|
104
|
-
|
|
105
|
-
The mapping above is what new authors see first. Authors with
|
|
106
|
-
Postgres background orient instantly. Authors without it get a
|
|
107
|
-
mental anchor with 30 years of Codd/SQL/PostgREST literature
|
|
108
|
-
behind it.
|
|
109
|
-
|
|
110
|
-
### Composition rule
|
|
111
|
-
|
|
112
|
-
Anything more domain-shaped than these 4 (a `Form`,
|
|
113
|
-
`Membership`, `Email`, `Webhook`, `Workflow`, `ScheduledJob`)
|
|
114
|
-
is **not** an atom. It is composed in the consumer project by
|
|
115
|
-
combining the 4 atoms with consumer TypeScript. If a proposed
|
|
116
|
-
new feature wants a 5th kind, the proposer must show the 4
|
|
117
|
-
existing atoms cannot express it.
|
|
118
|
-
|
|
119
|
-
## Consequences
|
|
120
|
-
|
|
121
|
-
### Pros
|
|
122
|
-
|
|
123
|
-
- One question — "is it state, a query, an operation, or an
|
|
124
|
-
event-binding?" — picks the atom every time. No "form vs
|
|
125
|
-
workflow" gray zone.
|
|
126
|
-
- Read/write asymmetry (Views auto-mount, Procedures require
|
|
127
|
-
Triggers) matches HTTP safe-vs-unsafe semantics. Authors don't
|
|
128
|
-
have to remember which kinds the SDK auto-routes; the rule is
|
|
129
|
-
derivable from the atom's nature.
|
|
130
|
-
- PG mapping gives the spec 30 years of literature and battle
|
|
131
|
-
testing as background. Postgres has shipped these primitives
|
|
132
|
-
in the same shape since SQL-92 (Schema, View, Procedure) plus
|
|
133
|
-
Active Database / ECA rules from the 1990s (Trigger).
|
|
134
|
-
- Closed atom count makes the SDK's testing surface tractable:
|
|
135
|
-
every code path can be enumerated as
|
|
136
|
-
Schema-creation / View-query / Procedure-invocation /
|
|
137
|
-
Trigger-firing combinations.
|
|
138
|
-
|
|
139
|
-
### Costs
|
|
140
|
-
|
|
141
|
-
- Atoms are coarse. A "form-with-validation-and-email" feature
|
|
142
|
-
is 3 manifests (Schema + Procedure + Trigger), not 1. Mitigated
|
|
143
|
-
by multi-doc YAML grouping (see § Authoring shape below).
|
|
144
|
-
- "Procedure is not directly exposed" is a teaching point; new
|
|
145
|
-
authors initially try to call a Procedure URL and get 404.
|
|
146
|
-
- The PG-1:1 pitch breaks down once authors look at the actual
|
|
147
|
-
storage layer (D1 today). The mapping is conceptual; the
|
|
148
|
-
runtime is SQLite + JSON.
|
|
149
|
-
|
|
150
|
-
### Risks
|
|
151
|
-
|
|
152
|
-
- **Authors try to subsume domain concepts into the 4 atoms by
|
|
153
|
-
cramming.** A `Form` becomes "a Schema + a Procedure + an
|
|
154
|
-
ad-hoc validator block in the handler." Mitigated by
|
|
155
|
-
multi-doc YAML keeping atoms separate while the file count
|
|
156
|
-
stays low; reviewers should push back when a single Procedure's
|
|
157
|
-
handler becomes a workflow engine.
|
|
158
|
-
- **Trigger.source.kind expansion pressure.** v0.1 ships `http`, `mcp`,
|
|
159
|
-
and `lifecycle`. Each new source kind requires a complete grammar and
|
|
160
|
-
runtime design pass.
|
|
161
|
-
- **The PG-1:1 pitch may become a constraint.** If a future
|
|
162
|
-
capability has no PG analogue, framing pressure will push to
|
|
163
|
-
shoehorn it into the table or to break the pitch. Either is
|
|
164
|
-
defensible; the discipline is to flag the choice consciously.
|
|
165
|
-
|
|
166
|
-
## Alternatives considered
|
|
167
|
-
|
|
168
|
-
**(a) 11 domain-shaped kinds (early scaffolding)**.
|
|
169
|
-
Rejected: cross-cutting features didn't fit single kinds;
|
|
170
|
-
adjacent kinds drifted toward overlap. Authors couldn't pick.
|
|
171
|
-
|
|
172
|
-
**(b) 5 kinds — keep `Policy` as a separate atom**.
|
|
173
|
-
Rejected: row/field-level policy is sub-spec on the atom whose
|
|
174
|
-
data it concerns (Schema-attached visibility, Procedure-attached
|
|
175
|
-
auth gate). Lifting Policy to a kind invented a 5th locator
|
|
176
|
-
authors had to consult; folding it kept the locator count down.
|
|
177
|
-
|
|
178
|
-
**(c) 3 kinds — fold Procedure into `Schema.operations`** (R6.5).
|
|
179
|
-
Rejected: under R7's reframing, the right axis is contract /
|
|
180
|
-
implementation × state / event, not "PG attachment." Schema
|
|
181
|
-
holds state; Procedure holds operations against state; folding
|
|
182
|
-
them conflates "what data exists" with "what can happen to data."
|
|
183
|
-
Also the LOC win that motivated the fold (92→58 via default CRUD)
|
|
184
|
-
was recovered without folding through the shipped
|
|
185
|
-
`handler.kind: builtin` shortcut.
|
|
186
|
-
|
|
187
|
-
**(d) 4 kinds with `Procedure` retaining inline
|
|
188
|
-
`expose: { http: ... }` for single-source bindings**.
|
|
189
|
-
Rejected: created two ways to bind HTTP (inline `expose:` for
|
|
190
|
-
single-source, separate `Trigger` for multi-source). Doctrine
|
|
191
|
-
tax forever. Multi-doc YAML solves the file-count complaint
|
|
192
|
-
that motivated `expose:` without inventing redundant grammar.
|
|
193
|
-
See § Authoring shape below for the full retirement rationale.
|
|
194
|
-
|
|
195
|
-
## How to apply
|
|
196
|
-
|
|
197
|
-
- Adding a new feature: ask which of the 4 atoms holds each
|
|
198
|
-
piece. Use the "external by itself?" column to settle "do I
|
|
199
|
-
need a Trigger here?"
|
|
200
|
-
- Adding a new top-level kind: do not. First express as a
|
|
201
|
-
composition of the 4 + consumer TS. If the composition is
|
|
202
|
-
awkward, look for sub-spec on an existing atom before adding
|
|
203
|
-
a 5th kind.
|
|
204
|
-
- Renaming an atom: do not. The names are public surface; even
|
|
205
|
-
internally-motivated renames tend to drag schema-revise effort
|
|
206
|
-
across consumers, code, docs, and agent training data. Bias
|
|
207
|
-
toward keeping the names.
|
|
208
|
-
- Reading the spec: Schema = state, View = read API,
|
|
209
|
-
Procedure = write API (internal), Trigger = binding. That
|
|
210
|
-
4-word gloss covers ~90% of the questions authors ask.
|
|
211
|
-
|
|
212
|
-
## Implementation status
|
|
213
|
-
|
|
214
|
-
Names + PG-1:1 framing are documented in this ADR and the manifest grammar
|
|
215
|
-
reference. Manifest TS types live in `packages/mantle-spec/`. The external
|
|
216
|
-
[`aotter/mantle-starters`](https://github.com/aotter/mantle-starters)
|
|
217
|
-
repository declared alpha-era consumer instances of each atom; new applications
|
|
218
|
-
are authored directly under [ADR-0021](0021-retire-starter-scaffolding.md).
|
|
219
|
-
Runtime dispatcher, View executor, and Procedure dispatcher live in this repository.
|
|
220
|
-
|
|
221
|
-
---
|
|
222
|
-
|
|
223
|
-
## Grammar changes
|
|
224
|
-
|
|
225
|
-
The parser accepts only grammar implemented by the current SDK. Unknown keys and
|
|
226
|
-
closed-enum values fail validation; Mantle does not reserve speculative syntax.
|
|
227
|
-
Add new grammar only alongside a concrete use case, runtime behavior, validation,
|
|
228
|
-
and an ADR update. Earlier experiments remain available in git history.
|
|
229
|
-
|
|
230
|
-
---
|
|
231
|
-
|
|
232
|
-
## Authoring shape: multi-doc YAML (was POC ADR-0006)
|
|
233
|
-
|
|
234
|
-
> Folded in 2026-05-03 from POC ADR-0006 ("Multi-doc YAML over
|
|
235
|
-
> inline shortcuts for atom co-location"). The decision below
|
|
236
|
-
> defines how authors lay manifests out on disk; it is the
|
|
237
|
-
> direct corollary of "Trigger does all binding" above.
|
|
238
|
-
|
|
239
|
-
### Context
|
|
240
|
-
|
|
241
|
-
The 4-atom model means a single user-visible feature commonly
|
|
242
|
-
bundles multiple atoms. A contact form is at minimum:
|
|
243
|
-
|
|
244
|
-
- A `Schema` for `contact-messages`
|
|
245
|
-
- A `Procedure` `send-contact-message` (handler validates +
|
|
246
|
-
inserts)
|
|
247
|
-
- A `Trigger` binding the Procedure to `POST /api/contact`
|
|
248
|
-
|
|
249
|
-
Three atoms, three documents. With one file per atom, a
|
|
250
|
-
small site with 10 features has 30+ manifest files. An early
|
|
251
|
-
design-experiment vibe-user called this out:
|
|
252
|
-
|
|
253
|
-
> 4 個 manifest 為了一顆 like 按鈕?要寫成這樣才能用?
|
|
254
|
-
|
|
255
|
-
(Translation: 4 manifests just for a like button? You have to
|
|
256
|
-
write all this to make it work?)
|
|
257
|
-
|
|
258
|
-
Two paths surfaced to address the file count:
|
|
259
|
-
|
|
260
|
-
#### Path A — Multi-doc YAML
|
|
261
|
-
|
|
262
|
-
YAML's standard `---` separator allows multiple documents in
|
|
263
|
-
one file. The fixed site manifest carries all atoms:
|
|
264
|
-
|
|
265
|
-
```yaml
|
|
266
|
-
# manifests/site.yaml
|
|
267
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
268
|
-
kind: Schema
|
|
269
|
-
metadata: { name: contact-messages }
|
|
270
|
-
spec:
|
|
271
|
-
schema: { ... }
|
|
272
|
-
|
|
273
|
-
---
|
|
274
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
275
|
-
kind: Procedure
|
|
276
|
-
metadata: { name: send-contact-message }
|
|
277
|
-
spec:
|
|
278
|
-
input: { ... }
|
|
279
|
-
output: { ... }
|
|
280
|
-
handler: { kind: ref, ref: send-contact-message }
|
|
281
|
-
|
|
282
|
-
---
|
|
283
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
284
|
-
kind: Trigger
|
|
285
|
-
metadata: { name: contact-http }
|
|
286
|
-
spec:
|
|
287
|
-
source: { kind: http, method: POST, path: /api/contact }
|
|
288
|
-
target: { procedure: send-contact-message }
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
One file, three atoms, conceptual separation preserved. The
|
|
292
|
-
loader reads `site.yaml` and parses each `---` block as a separate
|
|
293
|
-
manifest.
|
|
294
|
-
|
|
295
|
-
#### Path B — Inline shortcut on Procedure (`expose:`)
|
|
296
|
-
|
|
297
|
-
Add a `Procedure.expose:` block that absorbs single-source HTTP
|
|
298
|
-
binding inline, eliminating the Trigger for the 1:1 case:
|
|
299
|
-
|
|
300
|
-
```yaml
|
|
301
|
-
apiVersion: cms.mantle.aotter.net/v1
|
|
302
|
-
kind: Procedure
|
|
303
|
-
metadata: { name: send-contact-message }
|
|
304
|
-
spec:
|
|
305
|
-
expose:
|
|
306
|
-
http: { method: POST, path: /api/contact }
|
|
307
|
-
input: { ... }
|
|
308
|
-
output: { ... }
|
|
309
|
-
handler: { kind: ref, ref: send-contact-message }
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
The two paths solve the same surface concern (file count) but
|
|
313
|
-
have very different structural implications.
|
|
314
|
-
|
|
315
|
-
### Decision
|
|
316
|
-
|
|
317
|
-
**Path A: Multi-doc YAML.** `Procedure.expose:` is permanently
|
|
318
|
-
retired. Trigger does ALL transport binding. Co-locate related
|
|
319
|
-
atoms in one file via `---`.
|
|
320
|
-
|
|
321
|
-
#### Why Path B was retired
|
|
322
|
-
|
|
323
|
-
Path B created **two ways to bind a Procedure to HTTP**:
|
|
324
|
-
|
|
325
|
-
- For a Procedure with one HTTP transport: inline `expose:` on
|
|
326
|
-
Procedure
|
|
327
|
-
- For a Procedure with multiple transports (HTTP + MCP):
|
|
328
|
-
separate `Trigger` per transport
|
|
329
|
-
|
|
330
|
-
This is the exact "two ways to do the same thing" failure mode.
|
|
331
|
-
Doctrine resolves it on paper ("expose for single, Trigger for
|
|
332
|
-
multi") but creates permanent tax:
|
|
333
|
-
|
|
334
|
-
- Authors must remember which form to use, and switch when
|
|
335
|
-
cardinality changes (a single-HTTP Procedure that later
|
|
336
|
-
needs an MCP binding has to be refactored from `expose:` to
|
|
337
|
-
`Trigger`).
|
|
338
|
-
- The validator must understand both forms; OpenAPI emission
|
|
339
|
-
has two source paths to walk.
|
|
340
|
-
- The PG-1:1 mapping is muddied: "Procedure ≡ pg_proc" is clean
|
|
341
|
-
only if Procedure is internal-callable (no transport surface);
|
|
342
|
-
`expose:` gives Procedure transport semantics, weakening the
|
|
343
|
-
analogy.
|
|
344
|
-
- AI authors trying to introspect the manifest model get
|
|
345
|
-
conflicting signals about what the atom does.
|
|
346
|
-
|
|
347
|
-
#### What multi-doc YAML accomplishes
|
|
348
|
-
|
|
349
|
-
- File count drops without inventing redundancy. A site has one
|
|
350
|
-
authored manifest file regardless of how many atoms it requires.
|
|
351
|
-
- Atom separation stays honest. Every atom has its own
|
|
352
|
-
envelope (`apiVersion`, `kind`, `metadata`, `spec`); there
|
|
353
|
-
is no "shortcut form."
|
|
354
|
-
- Related atoms sit next to each other for readers reviewing the site.
|
|
355
|
-
- The PG-1:1 framing stays clean: Procedure is
|
|
356
|
-
internal-callable, Trigger is the binding atom.
|
|
357
|
-
|
|
358
|
-
#### Fixed file contract
|
|
359
|
-
|
|
360
|
-
The authored file is always `manifests/site.yaml`. The common loader rejects
|
|
361
|
-
a missing or differently named file, and every `---` document becomes one
|
|
362
|
-
atom. This is enforced so humans and agents never need a file-discovery rule.
|
|
363
|
-
|
|
364
|
-
### Consequences
|
|
365
|
-
|
|
366
|
-
#### Pros
|
|
367
|
-
|
|
368
|
-
- Single mechanism for HTTP binding (Trigger). Validator,
|
|
369
|
-
OpenAPI emitter, runtime dispatcher all walk one shape.
|
|
370
|
-
- Conceptual atom separation preserved. The 4-atom story holds
|
|
371
|
-
for every feature.
|
|
372
|
-
- File count is fixed at one authored manifest.
|
|
373
|
-
- Cardinality changes (1 HTTP → HTTP + cron) are additive (add
|
|
374
|
-
a Trigger); no refactor needed.
|
|
375
|
-
- AI authors learn one mental model, not two.
|
|
376
|
-
|
|
377
|
-
#### Costs
|
|
378
|
-
|
|
379
|
-
- Author must learn YAML's multi-doc syntax (`---`). This is
|
|
380
|
-
standard YAML 1.2 and supported by every loader, but it is
|
|
381
|
-
one more piece of syntax than "one file = one document."
|
|
382
|
-
- Some loaders (older / non-compliant) don't handle multi-doc.
|
|
383
|
-
Standard `js-yaml` / `yaml` libraries do; the SDK uses
|
|
384
|
-
`yaml` (already a dependency).
|
|
385
|
-
- Authors use `grep` by atom name inside `manifests/site.yaml` instead of
|
|
386
|
-
discovering feature-specific filenames.
|
|
387
|
-
- Editor support: YAML language servers handle multi-doc, but
|
|
388
|
-
some IDE features (e.g. JSON Schema validation per document
|
|
389
|
-
in a multi-doc file) work less smoothly than in single-doc
|
|
390
|
-
files. Acceptable for v0.1.
|
|
391
|
-
|
|
392
|
-
#### Risks
|
|
393
|
-
|
|
394
|
-
- **Author convenience pressure to reintroduce `expose:`.**
|
|
395
|
-
Someone shows up with "but for the 80% case where I have one
|
|
396
|
-
HTTP binding, the inline form is so much shorter!" The
|
|
397
|
-
argument is real; the answer is: doctrine that creates two
|
|
398
|
-
ways is permanent tax that grows with the codebase.
|
|
399
|
-
Mitigation: this section is the answer to that argument; flag
|
|
400
|
-
attempts and link here.
|
|
401
|
-
- **`site.yaml` can grow.** Search by `kind` plus `metadata.name`; reconsider
|
|
402
|
-
splitting only when real projects show that one deterministic location is
|
|
403
|
-
worse than file discovery.
|
|
404
|
-
|
|
405
|
-
### Alternatives considered
|
|
406
|
-
|
|
407
|
-
**(a) Path B: `Procedure.expose:`**.
|
|
408
|
-
Rejected (this section's main subject). Doctrine tax forever; PG
|
|
409
|
-
analogy weakened; cardinality refactor required when
|
|
410
|
-
single-source becomes multi-source.
|
|
411
|
-
|
|
412
|
-
**(b) One file per atom (early scaffolding default)**.
|
|
413
|
-
Rejected: file count complaint is real for multi-atom features.
|
|
414
|
-
Path A solves it without inventing redundancy.
|
|
415
|
-
|
|
416
|
-
**(c) New top-level kind `Feature` that bundles atoms**.
|
|
417
|
-
Rejected: turns a YAML file-organization concern into a spec
|
|
418
|
-
question. The 4-atom contract holds; an envelope-around-atoms
|
|
419
|
-
is structural noise.
|
|
420
|
-
|
|
421
|
-
**(d) Make Trigger optional with a default of "auto-mount the
|
|
422
|
-
Procedure at /api/p/<name>"**.
|
|
423
|
-
Rejected: hides the binding decision from the author, breaks
|
|
424
|
-
the PG-1:1 mapping (Procedures are not externally exposed by
|
|
425
|
-
themselves), and creates a third way to bind (this default +
|
|
426
|
-
explicit `Trigger` + explicit `expose:`).
|
|
427
|
-
|
|
428
|
-
### How to apply
|
|
429
|
-
|
|
430
|
-
- Authoring: put every atom in `manifests/site.yaml`, separated by `---`.
|
|
431
|
-
- Reviewing: when an author writes a Procedure with an inline
|
|
432
|
-
HTTP binding, push back with this section.
|
|
433
|
-
- Refactoring: a feature that grew from one HTTP binding to
|
|
434
|
-
HTTP + MCP doesn't change the Procedure; it adds one Trigger
|
|
435
|
-
in the same file.
|
|
436
|
-
- Tooling: SDK loader reads `<manifest-root>/site.yaml` and parses each `---`
|
|
437
|
-
block; static validator emits diagnostics
|
|
438
|
-
with file path + manifest pointer
|
|
439
|
-
(`site.yaml#/2/spec/from`) so multi-doc location stays
|
|
440
|
-
precise.
|