@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.
Files changed (495) hide show
  1. package/README.md +166 -298
  2. package/dist/auth/adapter.d.ts +32 -0
  3. package/dist/auth/adapter.js +288 -0
  4. package/dist/auth/admin.d.ts +3 -0
  5. package/dist/auth/admin.js +21 -0
  6. package/dist/auth/caller.d.ts +86 -0
  7. package/dist/auth/caller.js +155 -0
  8. package/dist/auth/hardening.d.ts +24 -0
  9. package/dist/auth/hardening.js +40 -0
  10. package/dist/auth/identity.d.ts +121 -0
  11. package/dist/auth/identity.js +203 -0
  12. package/dist/auth/oauth.d.ts +63 -0
  13. package/dist/auth/oauth.js +217 -0
  14. package/dist/auth/resource-seeds.js +10 -0
  15. package/dist/auth/routes.d.ts +32 -0
  16. package/dist/auth/routes.js +226 -0
  17. package/dist/build/compiler.d.ts +721 -0
  18. package/dist/build/compiler.js +7029 -0
  19. package/dist/build/spec/domain/model/ManifestGrammar.d.ts +439 -0
  20. package/dist/build/spec/domain/model/RuntimePlan.d.ts +168 -0
  21. package/dist/build/spec/domain/model/SqlIr.d.ts +129 -0
  22. package/dist/build/spec/domain/model/UserFields.d.ts +21 -0
  23. package/dist/build/spec/domain/service/PlanFingerprint.d.ts +7 -0
  24. package/dist/build/spec/kernel/diagnostic.d.ts +108 -0
  25. package/dist/bun/assets.d.ts +2 -0
  26. package/dist/bun/assets.js +24 -0
  27. package/dist/domain/adminOrder.js +24 -0
  28. package/dist/domain/columns.js +57 -0
  29. package/dist/domain/describe/chunk-ZVXBGP7Y.js +424 -0
  30. package/dist/domain/describe/index.d.ts +58 -0
  31. package/dist/domain/describe/index.js +115 -0
  32. package/dist/domain/describe/target-hash.d.ts +8 -0
  33. package/dist/domain/describe/target-hash.js +12 -0
  34. package/dist/domain/describe/targets.d.ts +40 -0
  35. package/dist/domain/entry.js +33 -0
  36. package/dist/domain/generated-tools.js +19 -0
  37. package/dist/domain/generation.d.ts +16 -0
  38. package/dist/domain/generation.js +1 -0
  39. package/dist/domain/input.js +17 -0
  40. package/dist/domain/model.js +1 -0
  41. package/dist/domain/paging.js +230 -0
  42. package/dist/domain/recipes.js +24 -0
  43. package/dist/domain/userReferences.js +5 -0
  44. package/dist/domain/wireScalars.js +47 -0
  45. package/dist/infrastructure/adminEntries.js +153 -0
  46. package/dist/infrastructure/adminPaging.js +72 -0
  47. package/dist/infrastructure/artifacts.js +71 -0
  48. package/dist/infrastructure/authSchema.js +83 -0
  49. package/dist/infrastructure/bundle.js +188 -0
  50. package/dist/infrastructure/cli.js +118 -0
  51. package/dist/infrastructure/generate.d.ts +12 -0
  52. package/dist/infrastructure/generate.js +189 -0
  53. package/dist/infrastructure/generateAuth.d.ts +8 -0
  54. package/dist/infrastructure/generateAuth.js +74 -0
  55. package/dist/infrastructure/help.js +60 -0
  56. package/dist/infrastructure/init.js +54 -0
  57. package/dist/infrastructure/inputs.js +41 -0
  58. package/dist/infrastructure/mounts.js +25 -0
  59. package/dist/infrastructure/wrangler.js +109 -0
  60. package/dist/kernel/authorization.d.ts +4 -0
  61. package/dist/kernel/authorization.js +16 -0
  62. package/dist/kernel/binds.d.ts +60 -0
  63. package/dist/kernel/binds.js +49 -0
  64. package/dist/kernel/caller-identity.d.ts +24 -0
  65. package/dist/kernel/caller-identity.js +22 -0
  66. package/dist/kernel/contract-error.d.ts +12 -0
  67. package/dist/kernel/contract-error.js +14 -0
  68. package/dist/kernel/contracts.d.ts +143 -0
  69. package/dist/kernel/contracts.js +97 -0
  70. package/dist/kernel/cron.d.ts +1 -0
  71. package/dist/kernel/cron.js +58 -0
  72. package/dist/kernel/dialect/common.d.ts +38 -0
  73. package/dist/kernel/dialect/common.js +6 -0
  74. package/dist/kernel/dialect/postgres.d.ts +16 -0
  75. package/dist/kernel/dialect/postgres.js +18 -0
  76. package/dist/kernel/dialect/sqlite.d.ts +20 -0
  77. package/dist/kernel/dialect/sqlite.js +34 -0
  78. package/dist/kernel/drain.d.ts +5 -0
  79. package/dist/kernel/drain.js +35 -0
  80. package/dist/kernel/driver/bun-sqlite.d.ts +19 -0
  81. package/dist/kernel/driver/bun-sqlite.js +77 -0
  82. package/dist/kernel/driver/d1.d.ts +24 -0
  83. package/dist/kernel/driver/d1.js +22 -0
  84. package/dist/kernel/driver/postgres.d.ts +25 -0
  85. package/dist/kernel/driver/postgres.js +99 -0
  86. package/dist/kernel/driver/transaction-context.d.ts +10 -0
  87. package/dist/kernel/driver/transaction-context.js +29 -0
  88. package/dist/kernel/email.d.ts +28 -0
  89. package/dist/kernel/email.js +38 -0
  90. package/dist/kernel/host-access.d.ts +10 -0
  91. package/dist/kernel/host-access.js +65 -0
  92. package/dist/kernel/host-caller.d.ts +39 -0
  93. package/dist/kernel/host-caller.js +56 -0
  94. package/dist/kernel/json-body.d.ts +4 -0
  95. package/dist/kernel/json-body.js +44 -0
  96. package/dist/kernel/mcp-apps.d.ts +69 -0
  97. package/dist/kernel/mcp-apps.js +40 -0
  98. package/dist/kernel/mcp-call.d.ts +5 -0
  99. package/dist/kernel/mcp-call.js +25 -0
  100. package/dist/kernel/mcp-handler.js +371 -0
  101. package/dist/kernel/mcp.d.ts +110 -0
  102. package/dist/kernel/mcp.js +50 -0
  103. package/dist/kernel/media.d.ts +27 -0
  104. package/dist/kernel/media.js +216 -0
  105. package/dist/kernel/paging.d.ts +55 -0
  106. package/dist/kernel/paging.js +95 -0
  107. package/dist/kernel/publishing.d.ts +4 -0
  108. package/dist/kernel/publishing.js +16 -0
  109. package/dist/kernel/r2-media.d.ts +42 -0
  110. package/dist/kernel/r2-media.js +78 -0
  111. package/dist/kernel/rest-dispatch.js +38 -0
  112. package/dist/kernel/rest-router.js +64 -0
  113. package/dist/kernel/rest.d.ts +58 -0
  114. package/dist/kernel/rest.js +41 -0
  115. package/dist/kernel/scalars.d.ts +6 -0
  116. package/dist/kernel/scalars.js +44 -0
  117. package/dist/kernel/search.js +5 -0
  118. package/dist/kernel/site-types.d.ts +146 -0
  119. package/dist/kernel/site-types.js +1 -0
  120. package/dist/kernel/site.d.ts +39 -0
  121. package/dist/kernel/site.js +32 -0
  122. package/dist/kernel/store.d.ts +175 -0
  123. package/dist/kernel/store.js +269 -0
  124. package/dist/kernel/surface.d.ts +10 -0
  125. package/dist/kernel/surface.js +19 -0
  126. package/dist/kernel/sweep.d.ts +17 -0
  127. package/dist/kernel/sweep.js +27 -0
  128. package/dist/kernel/translations.d.ts +1 -0
  129. package/dist/kernel/translations.js +13 -0
  130. package/dist/kernel/user-caller.d.ts +31 -0
  131. package/dist/kernel/user-caller.js +67 -0
  132. package/dist/kernel/user-field-name.js +3 -0
  133. package/dist/kernel/user-fields.d.ts +35 -0
  134. package/dist/kernel/user-fields.js +81 -0
  135. package/dist/kernel/validation.d.ts +15 -0
  136. package/dist/kernel/validation.js +54 -0
  137. package/dist/kernel/web-gateway.js +68 -0
  138. package/dist/kernel/web-head.js +15 -0
  139. package/dist/kernel/web-index.js +40 -0
  140. package/dist/kernel/web-response.js +8 -0
  141. package/dist/kernel/web.d.ts +77 -0
  142. package/dist/kernel/web.js +124 -0
  143. package/dist/kernel/where.js +27 -0
  144. package/dist/testing/index.d.ts +1 -0
  145. package/dist/testing/index.js +1 -0
  146. package/dist/usecase/adminBindings.js +143 -0
  147. package/dist/usecase/adminClient.js +87 -0
  148. package/dist/usecase/adminDescriptors.js +107 -0
  149. package/dist/usecase/generate.js +166 -0
  150. package/dist/usecase/handlers.js +21 -0
  151. package/dist/usecase/mcp-media.js +17 -0
  152. package/dist/usecase/mcp.js +100 -0
  153. package/dist/usecase/paging.js +71 -0
  154. package/dist/usecase/publishing.js +63 -0
  155. package/dist/usecase/refusals.js +27 -0
  156. package/dist/usecase/rest.js +54 -0
  157. package/dist/usecase/search.js +7 -0
  158. package/dist/usecase/site.js +39 -0
  159. package/dist/usecase/stores.js +64 -0
  160. package/dist/usecase/tool-version.js +9 -0
  161. package/dist/usecase/translations.js +78 -0
  162. package/dist/usecase/ttl.js +20 -0
  163. package/dist/usecase/validation.js +241 -0
  164. package/dist/usecase/web.js +23 -0
  165. package/docs/examples/README.md +39 -18
  166. package/docs/examples/app-shell/.dev.vars.example +4 -0
  167. package/docs/examples/app-shell/README.md +121 -0
  168. package/docs/examples/app-shell/accept.mjs +91 -0
  169. package/docs/examples/app-shell/gitignore +7 -0
  170. package/docs/examples/app-shell/package.json +43 -0
  171. package/docs/examples/app-shell/pnpm-workspace.yaml +8 -0
  172. package/docs/examples/app-shell/smoke-kit.mjs +168 -0
  173. package/docs/examples/app-shell/src/auth.ts +58 -0
  174. package/docs/examples/app-shell/src/handlers.ts +5 -0
  175. package/docs/examples/app-shell/src/index.ts +4 -0
  176. package/docs/examples/app-shell/src/routes.ts +14 -0
  177. package/docs/examples/app-shell/src/schedule.ts +8 -0
  178. package/docs/examples/app-shell/src/service.ts +70 -0
  179. package/docs/examples/app-shell/src/sign-in.ts +41 -0
  180. package/docs/examples/app-shell/src/signup.ts +8 -0
  181. package/docs/examples/app-shell/tsconfig.json +26 -0
  182. package/docs/examples/app-shell/worker-configuration.d.ts +22 -0
  183. package/docs/examples/app-shell/wrangler.jsonc +62 -0
  184. package/docs/examples/club-events/README.md +65 -0
  185. package/docs/examples/club-events/manifests/club-events.yaml +247 -0
  186. package/docs/examples/club-events/smoke.mjs +127 -0
  187. package/docs/examples/club-events/src/handlers.ts +25 -0
  188. package/docs/examples/club-events/src/signup.ts +9 -0
  189. package/docs/examples/generated-web/README.md +78 -0
  190. package/docs/examples/generated-web/posts.yaml +38 -0
  191. package/docs/examples/generated-web/seed.sql +6 -0
  192. package/docs/examples/generated-web/src/worker.ts +43 -0
  193. package/docs/examples/generated-web/tsconfig.json +8 -0
  194. package/docs/examples/generated-web/wrangler.jsonc +8 -0
  195. package/docs/examples/purchasing/.dev.vars.example +6 -0
  196. package/docs/examples/purchasing/README.md +99 -0
  197. package/docs/examples/purchasing/manifests/purchasing.yaml +374 -0
  198. package/docs/examples/purchasing/seed.sql +4 -0
  199. package/docs/examples/purchasing/smoke.mjs +191 -0
  200. package/docs/examples/purchasing/src/admin.tsx +13 -0
  201. package/docs/examples/purchasing/src/handlers.ts +33 -0
  202. package/docs/examples/purchasing/src/notify.ts +29 -0
  203. package/docs/examples/purchasing/src/requests-page.ts +57 -0
  204. package/docs/examples/purchasing/src/routes.ts +53 -0
  205. package/docs/examples/purchasing/src/schedule.ts +31 -0
  206. package/docs/examples/purchasing/src/signup.ts +5 -0
  207. package/docs/examples/purchasing/src/supplier.ts +32 -0
  208. package/docs/examples/purchasing/wrangler.jsonc +69 -0
  209. package/docs/examples/recipes/README.md +60 -0
  210. package/docs/examples/recipes/manifests/recipes.yaml +75 -0
  211. package/docs/examples/recipes/smoke.mjs +102 -0
  212. package/docs/examples/recipes/src/media.ts +13 -0
  213. package/docs/examples/recipes/src/pages.ts +99 -0
  214. package/docs/examples/recipes/src/routes.ts +71 -0
  215. package/docs/examples/recipes/src/site-config.ts +12 -0
  216. package/docs/examples/recipes/wrangler.jsonc +74 -0
  217. package/docs/handbook/cloudflare/authentication.md +180 -322
  218. package/docs/handbook/cloudflare/chatgpt-sites.md +5 -23
  219. package/docs/handbook/cloudflare/deploy-and-operate.md +55 -77
  220. package/docs/handbook/cloudflare/media-r2.md +61 -205
  221. package/docs/handbook/cloudflare/service-entry.md +239 -0
  222. package/docs/handbook/concepts/authorization.md +10 -107
  223. package/docs/handbook/concepts/four-atoms.md +9 -168
  224. package/docs/handbook/concepts/lifecycle-and-locales.md +9 -132
  225. package/docs/handbook/concepts/mcp-and-agents.md +24 -121
  226. package/docs/handbook/concepts/procedures-and-triggers.md +5 -217
  227. package/docs/handbook/concepts/runtime-and-adapters.md +15 -169
  228. package/docs/handbook/concepts/views.md +10 -185
  229. package/docs/handbook/examples/hub.md +3 -8
  230. package/docs/handbook/guides/adapter-guide.md +11 -0
  231. package/docs/handbook/guides/admin-ui.md +115 -133
  232. package/docs/handbook/guides/agent-setup.md +64 -74
  233. package/docs/handbook/guides/agent-workflow-acceptance.md +232 -0
  234. package/docs/handbook/guides/email.md +86 -0
  235. package/docs/handbook/guides/local-testing.md +40 -0
  236. package/docs/handbook/guides/mcp-apps.md +560 -0
  237. package/docs/handbook/guides/native-admin.md +566 -0
  238. package/docs/handbook/guides/native-execution.md +133 -0
  239. package/docs/handbook/guides/oauth.md +219 -0
  240. package/docs/handbook/guides/postgres-adapters.md +56 -0
  241. package/docs/handbook/guides/public-pages.md +87 -0
  242. package/docs/handbook/guides/size-and-startup.md +9 -0
  243. package/docs/handbook/guides/sql-patterns.md +266 -0
  244. package/docs/handbook/guides/typed-queries.md +211 -107
  245. package/docs/handbook/navigation.json +176 -55
  246. package/docs/handbook/reference/admin-descriptors.md +53 -0
  247. package/docs/handbook/reference/authorization.md +39 -266
  248. package/docs/handbook/reference/describe.md +56 -0
  249. package/docs/handbook/reference/diagnostics.md +19 -186
  250. package/docs/handbook/reference/features.md +45 -55
  251. package/docs/handbook/reference/manifest.md +6 -129
  252. package/docs/handbook/reference/procedure.md +11 -303
  253. package/docs/handbook/reference/schema.md +64 -240
  254. package/docs/handbook/reference/site-config.md +5 -218
  255. package/docs/handbook/reference/sql.md +64 -0
  256. package/docs/handbook/reference/surface.md +392 -201
  257. package/docs/handbook/reference/trigger.md +56 -192
  258. package/docs/handbook/reference/view.md +24 -243
  259. package/docs/handbook/releases/index.md +244 -77
  260. package/docs/handbook/start/agents.md +45 -0
  261. package/docs/handbook/start/overview.md +9 -48
  262. package/docs/handbook/start/project-and-cli.md +51 -104
  263. package/docs/handbook/start/quickstart-worker.md +43 -178
  264. package/docs/skills/develop/SKILL.md +79 -249
  265. package/docs/skills/integrate/SKILL.md +39 -50
  266. package/docs/skills/media-gc/SKILL.md +34 -10
  267. package/docs/skills/provision/SKILL.md +36 -186
  268. package/docs/skills/update/SKILL.md +23 -38
  269. package/docs/source/scripts/postgres-adapter.ts +101 -0
  270. package/docs/upgrade-0.1-to-0.2.md +227 -0
  271. package/package.json +120 -131
  272. package/skills/README.md +48 -108
  273. package/skills/mantle/SKILL.md +76 -0
  274. package/dist/admin-ui.d.ts +0 -2
  275. package/dist/admin-ui.d.ts.map +0 -1
  276. package/dist/admin-ui.js +0 -2
  277. package/dist/admin-ui.js.map +0 -1
  278. package/dist/admin.d.ts +0 -2
  279. package/dist/admin.d.ts.map +0 -1
  280. package/dist/admin.js +0 -2
  281. package/dist/admin.js.map +0 -1
  282. package/dist/auth.d.ts +0 -2
  283. package/dist/auth.d.ts.map +0 -1
  284. package/dist/auth.js +0 -2
  285. package/dist/auth.js.map +0 -1
  286. package/dist/bun.d.ts +0 -2
  287. package/dist/bun.d.ts.map +0 -1
  288. package/dist/bun.js +0 -2
  289. package/dist/bun.js.map +0 -1
  290. package/dist/cli/generate-cloudflare.d.ts +0 -7
  291. package/dist/cli/generate-cloudflare.d.ts.map +0 -1
  292. package/dist/cli/generate-cloudflare.js +0 -123
  293. package/dist/cli/generate-cloudflare.js.map +0 -1
  294. package/dist/cli/generate-project.d.ts +0 -25
  295. package/dist/cli/generate-project.d.ts.map +0 -1
  296. package/dist/cli/generate-project.js +0 -282
  297. package/dist/cli/generate-project.js.map +0 -1
  298. package/dist/cli/generate-sites.d.ts +0 -8
  299. package/dist/cli/generate-sites.d.ts.map +0 -1
  300. package/dist/cli/generate-sites.js +0 -273
  301. package/dist/cli/generate-sites.js.map +0 -1
  302. package/dist/cli/generate.d.ts +0 -20
  303. package/dist/cli/generate.d.ts.map +0 -1
  304. package/dist/cli/generate.js +0 -299
  305. package/dist/cli/generate.js.map +0 -1
  306. package/dist/cli/harness.d.ts +0 -3
  307. package/dist/cli/harness.d.ts.map +0 -1
  308. package/dist/cli/harness.js +0 -214
  309. package/dist/cli/harness.js.map +0 -1
  310. package/dist/cli/main.d.ts +0 -3
  311. package/dist/cli/main.d.ts.map +0 -1
  312. package/dist/cli/main.js +0 -77
  313. package/dist/cli/main.js.map +0 -1
  314. package/dist/cli/skills.d.ts +0 -3
  315. package/dist/cli/skills.d.ts.map +0 -1
  316. package/dist/cli/skills.js +0 -128
  317. package/dist/cli/skills.js.map +0 -1
  318. package/dist/cloudflare.d.ts +0 -2
  319. package/dist/cloudflare.d.ts.map +0 -1
  320. package/dist/cloudflare.js +0 -2
  321. package/dist/cloudflare.js.map +0 -1
  322. package/dist/codegen/emitMantleModule.d.ts +0 -22
  323. package/dist/codegen/emitMantleModule.d.ts.map +0 -1
  324. package/dist/codegen/emitMantleModule.js +0 -291
  325. package/dist/codegen/emitMantleModule.js.map +0 -1
  326. package/dist/codegen.d.ts +0 -2
  327. package/dist/codegen.d.ts.map +0 -1
  328. package/dist/codegen.js +0 -2
  329. package/dist/codegen.js.map +0 -1
  330. package/dist/runtime-testing.d.ts +0 -2
  331. package/dist/runtime-testing.d.ts.map +0 -1
  332. package/dist/runtime-testing.js +0 -2
  333. package/dist/runtime-testing.js.map +0 -1
  334. package/dist/runtime.d.ts +0 -2
  335. package/dist/runtime.d.ts.map +0 -1
  336. package/dist/runtime.js +0 -2
  337. package/dist/runtime.js.map +0 -1
  338. package/dist/spec.d.ts +0 -2
  339. package/dist/spec.d.ts.map +0 -1
  340. package/dist/spec.js +0 -2
  341. package/dist/spec.js.map +0 -1
  342. package/dist/vercel-libsql.d.ts +0 -2
  343. package/dist/vercel-libsql.d.ts.map +0 -1
  344. package/dist/vercel-libsql.js +0 -2
  345. package/dist/vercel-libsql.js.map +0 -1
  346. package/dist/vercel.d.ts +0 -2
  347. package/dist/vercel.d.ts.map +0 -1
  348. package/dist/vercel.js +0 -2
  349. package/dist/vercel.js.map +0 -1
  350. package/dist/web.d.ts +0 -2
  351. package/dist/web.d.ts.map +0 -1
  352. package/dist/web.js +0 -2
  353. package/dist/web.js.map +0 -1
  354. package/docs/adapter-guide.md +0 -222
  355. package/docs/adr/0001-four-atom-manifest-model.md +0 -440
  356. package/docs/adr/0002-closed-enums-for-bindings.md +0 -253
  357. package/docs/adr/0007-ai-as-primary-author.md +0 -473
  358. package/docs/adr/0008-structured-diagnostic-shape.md +0 -338
  359. package/docs/adr/0009-consumer-supplied-manifests.md +0 -149
  360. package/docs/adr/0010-locale-and-translates.md +0 -453
  361. package/docs/adr/0011-adapter-port-spec.md +0 -281
  362. package/docs/adr/0012-views-as-public-rest.md +0 -161
  363. package/docs/adr/0013-agent-provisioned-consumer-projects.md +0 -154
  364. package/docs/adr/0014-auth-better-auth-and-multi-tenant-mcp.md +0 -900
  365. package/docs/adr/0016-site-semantic-layer.md +0 -70
  366. package/docs/adr/0017-media-multi-variant-agent-side-optimization.md +0 -181
  367. package/docs/adr/0018-core-starters-repository-boundary.md +0 -179
  368. package/docs/adr/0019-sealed-manifest-runtime-pipeline.md +0 -240
  369. package/docs/adr/0020-builtin-handler-contracts-and-matched-upsert.md +0 -199
  370. package/docs/adr/0021-retire-starter-scaffolding.md +0 -30
  371. package/docs/adr/0022-caller-observed-version-occ.md +0 -212
  372. package/docs/adr/0023-port-failure-contract.md +0 -69
  373. package/docs/adr/0024-manifest-native-schema-tables.md +0 -264
  374. package/docs/adr/0025-reserved-native-columns-and-published-only-public-views.md +0 -105
  375. package/docs/adr/0026-progressive-generate.md +0 -36
  376. package/docs/adr/0027-scheduled-procedure-triggers.md +0 -31
  377. package/docs/adr/0028-schema-ttl-expiry.md +0 -33
  378. package/docs/adr/README.md +0 -81
  379. package/docs/adr/adr-lite-803-request-diagnostics.md +0 -38
  380. package/docs/adr/adr-lite-808-route-readiness.md +0 -47
  381. package/docs/adr/adr-lite-809-bounded-public-content.md +0 -71
  382. package/docs/adr/adr-lite-812-native-parity.md +0 -150
  383. package/docs/adr/adr-lite-823-home-statistics.md +0 -64
  384. package/docs/adr/adr-lite-842-mcp-authoring.md +0 -30
  385. package/docs/adr/adr-lite-845-frontend-client.md +0 -38
  386. package/docs/adr/adr-lite-861-admin-webmcp.md +0 -42
  387. package/docs/adr/adr-lite-909-admin-ui-kit.md +0 -37
  388. package/docs/agent-prompts.md +0 -64
  389. package/docs/api-mcp-authorization.md +0 -5
  390. package/docs/assets/mantle-admin-developer.png +0 -0
  391. package/docs/assets/mantle-admin-operations.png +0 -0
  392. package/docs/assets/mantle-hero.jpg +0 -0
  393. package/docs/auth-hosting-model.md +0 -166
  394. package/docs/cloudflare-low-level-composition.md +0 -5
  395. package/docs/consumer-onboarding-audit.md +0 -65
  396. package/docs/deferred-lifecycle-queues.md +0 -5
  397. package/docs/design-atoms.md +0 -16
  398. package/docs/design-references/editorial-blog-2026-05-05.md +0 -218
  399. package/docs/direct-authoring.md +0 -5
  400. package/docs/examples/builtin-commerce.md +0 -269
  401. package/docs/examples/builtin-intake.md +0 -143
  402. package/docs/examples/builtin-legal-documents.md +0 -189
  403. package/docs/examples/builtin-procurement.md +0 -241
  404. package/docs/examples/builtin-publication.md +0 -241
  405. package/docs/examples/builtin-reservation.md +0 -149
  406. package/docs/examples/cf-primitives-commerce-inventory.md +0 -809
  407. package/docs/examples/cf-primitives-guarded-api.md +0 -429
  408. package/docs/examples/cf-primitives-intake-hooks.md +0 -319
  409. package/docs/examples/host-chatgpt-sites/.openai/hosting.json +0 -1
  410. package/docs/examples/host-chatgpt-sites/README.md +0 -70
  411. package/docs/examples/host-chatgpt-sites/drizzle/0000_sites_users.sql +0 -8
  412. package/docs/examples/host-chatgpt-sites/drizzle/0001_mantle.sql +0 -294
  413. package/docs/examples/host-chatgpt-sites/drizzle/0002_article_cover.sql +0 -5
  414. package/docs/examples/host-chatgpt-sites/drizzle/0003_store_instance_id.sql +0 -1
  415. package/docs/examples/host-chatgpt-sites/drizzle/0004_mantle.sql +0 -10
  416. package/docs/examples/host-chatgpt-sites/drizzle/0005_mantle.sql +0 -24
  417. package/docs/examples/host-chatgpt-sites/drizzle/meta/_journal.json +0 -1
  418. package/docs/examples/host-chatgpt-sites/drizzle/meta/mantle-state.json +0 -60
  419. package/docs/examples/host-chatgpt-sites/manifests/site.yaml +0 -27
  420. package/docs/examples/host-chatgpt-sites/package.json +0 -1
  421. package/docs/examples/host-chatgpt-sites/public/site.css +0 -1
  422. package/docs/examples/host-chatgpt-sites/scripts/build.mjs +0 -13
  423. package/docs/examples/host-chatgpt-sites/scripts/check.mjs +0 -101
  424. package/docs/examples/host-chatgpt-sites/scripts/migration.mjs +0 -43
  425. package/docs/examples/host-chatgpt-sites/src/chatgpt-auth.ts +0 -66
  426. package/docs/examples/host-chatgpt-sites/src/index.ts +0 -46
  427. package/docs/examples/host-chatgpt-sites/src/mcp.ts +0 -49
  428. package/docs/examples/host-chatgpt-sites/src/media.ts +0 -109
  429. package/docs/examples/host-chatgpt-sites/src/r2-lab.ts +0 -38
  430. package/docs/examples/host-chatgpt-sites/src/storage-fingerprint.json +0 -1
  431. package/docs/examples/host-chatgpt-sites/src/web.ts +0 -35
  432. package/docs/examples/host-chatgpt-sites/tsconfig.json +0 -1
  433. package/docs/examples/host-chatgpt-sites/wrangler.jsonc +0 -10
  434. package/docs/examples/host-local-admin-otp/.dev.vars.example +0 -3
  435. package/docs/examples/host-local-admin-otp/README.md +0 -80
  436. package/docs/examples/host-local-admin-otp/ensure-dev-vars.mjs +0 -5
  437. package/docs/examples/host-local-admin-otp/manifests/site.yaml +0 -25
  438. package/docs/examples/host-local-admin-otp/package.json +0 -29
  439. package/docs/examples/host-local-admin-otp/public/.gitkeep +0 -1
  440. package/docs/examples/host-local-admin-otp/smoke.mjs +0 -141
  441. package/docs/examples/host-local-admin-otp/src/index.ts +0 -54
  442. package/docs/examples/host-local-admin-otp/tsconfig.json +0 -17
  443. package/docs/examples/host-local-admin-otp/wrangler.jsonc +0 -23
  444. package/docs/examples/host-minimal-worker/README.md +0 -41
  445. package/docs/examples/host-minimal-worker/manifests/site.yaml +0 -25
  446. package/docs/examples/host-minimal-worker/package.json +0 -26
  447. package/docs/examples/host-minimal-worker/smoke.mjs +0 -23
  448. package/docs/examples/host-minimal-worker/src/index.ts +0 -4
  449. package/docs/examples/host-minimal-worker/tsconfig.json +0 -17
  450. package/docs/examples/host-minimal-worker/wrangler.jsonc +0 -22
  451. package/docs/handbook/chatgpt-sites/equipment-checkout.md +0 -231
  452. package/docs/handbook/chatgpt-sites/generated-app.md +0 -84
  453. package/docs/handbook/chatgpt-sites/host-reference.md +0 -113
  454. package/docs/handbook/chatgpt-sites/index.md +0 -133
  455. package/docs/handbook/cloudflare/bindings.md +0 -291
  456. package/docs/handbook/cloudflare/conventional-worker.md +0 -166
  457. package/docs/handbook/cloudflare/deferred-hooks-queues.md +0 -170
  458. package/docs/handbook/cloudflare/low-level-composition.md +0 -169
  459. package/docs/handbook/cloudflare/public-web.md +0 -144
  460. package/docs/handbook/cloudflare/site-chrome.md +0 -75
  461. package/docs/handbook/examples/commerce-transaction.md +0 -11
  462. package/docs/handbook/examples/commerce.md +0 -11
  463. package/docs/handbook/examples/guarded-api.md +0 -10
  464. package/docs/handbook/examples/intake-form.md +0 -12
  465. package/docs/handbook/examples/intake-hooks.md +0 -11
  466. package/docs/handbook/examples/legal-documents.md +0 -10
  467. package/docs/handbook/examples/procurement-approvals.md +0 -10
  468. package/docs/handbook/examples/publication.md +0 -10
  469. package/docs/handbook/examples/reservation.md +0 -10
  470. package/docs/handbook/start/quickstart-admin.md +0 -52
  471. package/docs/labels.md +0 -71
  472. package/docs/media-uploads.md +0 -5
  473. package/docs/migration-0.1.2.md +0 -13
  474. package/docs/performance-harness.md +0 -228
  475. package/docs/release-process.md +0 -244
  476. package/docs/schema-indexes.md +0 -5
  477. package/docs/sealed-pipeline-ownership.md +0 -101
  478. package/docs/skills/plugin/SKILL.md +0 -132
  479. package/docs/skills/theme/SKILL.md +0 -77
  480. package/docs/spec-only-host-adoption.md +0 -157
  481. package/docs/transaction-patterns.md +0 -5
  482. package/skills/develop/SKILL.md +0 -258
  483. package/skills/install/SKILL.md +0 -112
  484. package/skills/integrate/SKILL.md +0 -60
  485. package/skills/media-gc/SKILL.md +0 -85
  486. package/skills/plugin/SKILL.md +0 -132
  487. package/skills/provision/SKILL.md +0 -194
  488. package/skills/theme/SKILL.md +0 -77
  489. package/skills/update/SKILL.md +0 -51
  490. package/templates/chatgpt-sites/auth.ts +0 -66
  491. package/templates/chatgpt-sites/build.mjs +0 -14
  492. package/templates/chatgpt-sites/env.ts +0 -1
  493. package/templates/chatgpt-sites/mcp.ts +0 -48
  494. package/templates/chatgpt-sites/public-mcp.ts +0 -29
  495. 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
- `requires` is the whole authorization grammar. It appears on [Procedure](./procedure.md) and [View](./view.md) and nowhere else; Schemas and Triggers carry no `requires`. This page is the field-level contract and the runtime behaviour it produces. The narrative version is [Authorization](../concepts/authorization.md), and a worked deployment is [Guarded API](../../examples/cf-primitives-guarded-api.md). Diagnostic codes named here are catalogued in [Diagnostics](./diagnostics.md).
7
-
8
- ## `requires`
3
+ Views and Procedures accept:
9
4
 
10
5
  ```yaml
11
- spec:
12
- requires:
13
- auth:
14
- all:
15
- - ctx.auth
16
- - ctx.user
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
- | Key | Type | Required | Rules |
23
- |---|---|---|---|
24
- | `requires` | mapping | no | Omitted means the target is anonymous. Only `auth` and `guard` are accepted. |
25
- | `requires.auth` | mapping | no | Only `all` is accepted. `any`, `none` and negation do not exist in v0.1. |
26
- | `requires.auth.all` | array | yes when `auth` is present | Non-empty array of predicates. Every entry must pass. |
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
- The vocabulary is closed. A bare string form is either `ctx.user` or `ctx.auth`; an object form carries exactly one key.
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
- | Predicate | Written as | Passes when |
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
- | Validation rule | Diagnostic |
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
- Scope strings are opaque to Core. Mantle neither issues credentials nor defines a scope catalog; the deployment owns both.
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
- ## Denial
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
- Predicates are evaluated in declaration order and the first failure denies the call.
30
+ ## User fields
55
31
 
56
- | Caller state | Code | HTTP |
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
- Both diagnostics carry the failing predicate's position: the `path` is `<target path>#/requires/auth/all/<i>`, where `<target path>` is `manifest:Procedure/<name>` or `manifest:View/<name>` unless the caller supplied its own prefix. `expected` describes the predicate in prose; the offending value is not echoed. An auth-gated View invoked with no caller context at all is denied `UNAUTHENTICATED` at `<target path>#/requires/auth` before any predicate runs.
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
- ## Guards
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
- `requires.guard.procedure` names one ordinary Procedure. It is not a fifth atom, and it is not a policy language: it is a handler that is allowed to say no.
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
- - The guard receives the target's **already-validated** input (Procedure) or params (View) and the **same** `HandlerContext`.
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
- | Rule | Diagnostic | Where checked |
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
- All four report at `<target path>#/requires/guard/procedure`; diagnostics raised inside the guard itself are prefixed `<target path>#/requires/guard/<guard name>`. The runtime repeats every check the validator already made, so a boot-bypassing embedding still fails closed.
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
- A guard denies by throwing a `DiagnosticError` carrying a runtime diagnostic. `ENTITLEMENT_REQUIRED` (`402`) is the conventional code for "verified caller, current business state says no" — an expired subscription, a revoked entitlement, an unpaid invoice. Any other runtime code works the same way and maps through the [status table](./diagnostics.md#runtime).
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
- ## Staff roles
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
- | Role | Rank | Capabilities |
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
- `users` is the base identity layer; `staff` is a privilege overlay with one row per privileged user, so `ctx.staff.id` always equals `ctx.user.id`. A signed-in user with no staff row is an ordinary site member with no Admin access and no `/mcp/staff` access.
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
- Rank ordering exists for "this role or above" gates — Admin's own route table uses it, so an `owner` passes an `editor`-gated Admin route. Generic staff MCP tools (including Admin WebMCP) use the same rank table: contributors may call `create_draft_*` / `update_draft_*`; publish, unpublish, archive, delete, media, and operational `create_record_*` / `update_record_*` require editor or owner. Declared Procedures still use their own `requires.auth.all`. The manifest predicate does not rank-order: `{ "ctx.staff": [editor] }` admits editors only. List every role you mean.
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
- The adapter re-reads the caller's current role from the database on every protected request. A role is never taken from a token, a consent snapshot or a cached catalog, so a demotion takes effect on the next call.
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
- ## `HandlerContext`
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
- interface HandlerContext<Env = unknown> {
103
- readonly user: { readonly id: string } | null;
104
- readonly staff: { readonly id: string; readonly role: StaffRole } | null;
105
- readonly auth?: {
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
- The guard handler denies with a structured diagnostic rather than a thrown string, so the boundary emits `402` instead of the `INTERNAL_ERROR` envelope:
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.