@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,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.