@xemahq/kernel-contracts 0.1.0 → 0.2.1

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 (280) hide show
  1. package/LICENSE +201 -0
  2. package/dist/agent-tool-inquiry/index.d.ts +2 -0
  3. package/dist/agent-tool-inquiry/index.d.ts.map +1 -0
  4. package/dist/agent-tool-inquiry/index.js +18 -0
  5. package/dist/agent-tool-inquiry/index.js.map +1 -0
  6. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.d.ts +43 -0
  7. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.d.ts.map +1 -0
  8. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.js +32 -0
  9. package/dist/agent-tool-inquiry/lib/agent-tool-inquiry.js.map +1 -0
  10. package/dist/agent-workspace/awp-spec.json +1 -1
  11. package/dist/app-runtime/index.d.ts +9 -0
  12. package/dist/app-runtime/index.d.ts.map +1 -0
  13. package/dist/app-runtime/index.js +25 -0
  14. package/dist/app-runtime/index.js.map +1 -0
  15. package/dist/app-runtime/lib/app-client.d.ts +11 -0
  16. package/dist/app-runtime/lib/app-client.d.ts.map +1 -0
  17. package/dist/app-runtime/lib/app-client.js +23 -0
  18. package/dist/app-runtime/lib/app-client.js.map +1 -0
  19. package/dist/app-runtime/lib/app-lockfile.d.ts +12 -0
  20. package/dist/app-runtime/lib/app-lockfile.d.ts.map +1 -0
  21. package/dist/app-runtime/lib/app-lockfile.js +17 -0
  22. package/dist/app-runtime/lib/app-lockfile.js.map +1 -0
  23. package/dist/app-runtime/lib/app.d.ts +26 -0
  24. package/dist/app-runtime/lib/app.d.ts.map +1 -0
  25. package/dist/app-runtime/lib/app.js +31 -0
  26. package/dist/app-runtime/lib/app.js.map +1 -0
  27. package/dist/app-runtime/lib/audience-policy.d.ts +31 -0
  28. package/dist/app-runtime/lib/audience-policy.d.ts.map +1 -0
  29. package/dist/app-runtime/lib/audience-policy.js +38 -0
  30. package/dist/app-runtime/lib/audience-policy.js.map +1 -0
  31. package/dist/app-runtime/lib/biome-install.d.ts +9 -0
  32. package/dist/app-runtime/lib/biome-install.d.ts.map +1 -0
  33. package/dist/app-runtime/lib/biome-install.js +13 -0
  34. package/dist/app-runtime/lib/biome-install.js.map +1 -0
  35. package/dist/app-runtime/lib/branding-config.d.ts +9 -0
  36. package/dist/app-runtime/lib/branding-config.d.ts.map +1 -0
  37. package/dist/app-runtime/lib/branding-config.js +24 -0
  38. package/dist/app-runtime/lib/branding-config.js.map +1 -0
  39. package/dist/app-runtime/lib/delegated-session.d.ts +15 -0
  40. package/dist/app-runtime/lib/delegated-session.d.ts.map +1 -0
  41. package/dist/app-runtime/lib/delegated-session.js +29 -0
  42. package/dist/app-runtime/lib/delegated-session.js.map +1 -0
  43. package/dist/app-runtime/lib/external-subject.d.ts +9 -0
  44. package/dist/app-runtime/lib/external-subject.d.ts.map +1 -0
  45. package/dist/app-runtime/lib/external-subject.js +19 -0
  46. package/dist/app-runtime/lib/external-subject.js.map +1 -0
  47. package/dist/connector/index.d.ts +9 -0
  48. package/dist/connector/index.d.ts.map +1 -0
  49. package/dist/connector/index.js +25 -0
  50. package/dist/connector/index.js.map +1 -0
  51. package/dist/connector/lib/adapter-kind.d.ts +8 -0
  52. package/dist/connector/lib/adapter-kind.d.ts.map +1 -0
  53. package/dist/connector/lib/adapter-kind.js +14 -0
  54. package/dist/connector/lib/adapter-kind.js.map +1 -0
  55. package/dist/connector/lib/capability-refs.d.ts +14 -0
  56. package/dist/connector/lib/capability-refs.d.ts.map +1 -0
  57. package/dist/connector/lib/capability-refs.js +15 -0
  58. package/dist/connector/lib/capability-refs.js.map +1 -0
  59. package/dist/connector/lib/capability.d.ts +18 -0
  60. package/dist/connector/lib/capability.d.ts.map +1 -0
  61. package/dist/connector/lib/capability.js +24 -0
  62. package/dist/connector/lib/capability.js.map +1 -0
  63. package/dist/connector/lib/credential-kind.d.ts +42 -0
  64. package/dist/connector/lib/credential-kind.d.ts.map +1 -0
  65. package/dist/connector/lib/credential-kind.js +26 -0
  66. package/dist/connector/lib/credential-kind.js.map +1 -0
  67. package/dist/connector/lib/envelope-schema.d.ts +6 -0
  68. package/dist/connector/lib/envelope-schema.d.ts.map +1 -0
  69. package/dist/connector/lib/envelope-schema.js +150 -0
  70. package/dist/connector/lib/envelope-schema.js.map +1 -0
  71. package/dist/connector/lib/filter-expr-schema.d.ts +4 -0
  72. package/dist/connector/lib/filter-expr-schema.d.ts.map +1 -0
  73. package/dist/connector/lib/filter-expr-schema.js +65 -0
  74. package/dist/connector/lib/filter-expr-schema.js.map +1 -0
  75. package/dist/connector/lib/filter-expr-validate.d.ts +10 -0
  76. package/dist/connector/lib/filter-expr-validate.d.ts.map +1 -0
  77. package/dist/connector/lib/filter-expr-validate.js +58 -0
  78. package/dist/connector/lib/filter-expr-validate.js.map +1 -0
  79. package/dist/connector/lib/filter-expr.d.ts +49 -0
  80. package/dist/connector/lib/filter-expr.d.ts.map +1 -0
  81. package/dist/connector/lib/filter-expr.js +135 -0
  82. package/dist/connector/lib/filter-expr.js.map +1 -0
  83. package/dist/connector/lib/onboarding-manifest.d.ts +45 -0
  84. package/dist/connector/lib/onboarding-manifest.d.ts.map +1 -0
  85. package/dist/connector/lib/onboarding-manifest.js +30 -0
  86. package/dist/connector/lib/onboarding-manifest.js.map +1 -0
  87. package/dist/document-render/index.d.ts +7 -0
  88. package/dist/document-render/index.d.ts.map +1 -0
  89. package/dist/document-render/index.js +23 -0
  90. package/dist/document-render/index.js.map +1 -0
  91. package/dist/document-render/lib/measure-layout.d.ts +44 -0
  92. package/dist/document-render/lib/measure-layout.d.ts.map +1 -0
  93. package/dist/document-render/lib/measure-layout.js +16 -0
  94. package/dist/document-render/lib/measure-layout.js.map +1 -0
  95. package/dist/document-render/lib/render-enums.d.ts +18 -0
  96. package/dist/document-render/lib/render-enums.d.ts.map +1 -0
  97. package/dist/document-render/lib/render-enums.js +24 -0
  98. package/dist/document-render/lib/render-enums.js.map +1 -0
  99. package/dist/document-render/lib/render-record.d.ts +22 -0
  100. package/dist/document-render/lib/render-record.d.ts.map +1 -0
  101. package/dist/document-render/lib/render-record.js +3 -0
  102. package/dist/document-render/lib/render-record.js.map +1 -0
  103. package/dist/document-render/lib/render-request.d.ts +24 -0
  104. package/dist/document-render/lib/render-request.d.ts.map +1 -0
  105. package/dist/document-render/lib/render-request.js +12 -0
  106. package/dist/document-render/lib/render-request.js.map +1 -0
  107. package/dist/document-render/lib/render-source.d.ts +43 -0
  108. package/dist/document-render/lib/render-source.d.ts.map +1 -0
  109. package/dist/document-render/lib/render-source.js +31 -0
  110. package/dist/document-render/lib/render-source.js.map +1 -0
  111. package/dist/document-render/lib/xema-prompt.d.ts +11 -0
  112. package/dist/document-render/lib/xema-prompt.d.ts.map +1 -0
  113. package/dist/document-render/lib/xema-prompt.js +46 -0
  114. package/dist/document-render/lib/xema-prompt.js.map +1 -0
  115. package/dist/inquiry/index.d.ts +7 -0
  116. package/dist/inquiry/index.d.ts.map +1 -0
  117. package/dist/inquiry/index.js +23 -0
  118. package/dist/inquiry/index.js.map +1 -0
  119. package/dist/inquiry/lib/enums.d.ts +36 -0
  120. package/dist/inquiry/lib/enums.d.ts.map +1 -0
  121. package/dist/inquiry/lib/enums.js +45 -0
  122. package/dist/inquiry/lib/enums.js.map +1 -0
  123. package/dist/inquiry/lib/inquiry.d.ts +332 -0
  124. package/dist/inquiry/lib/inquiry.d.ts.map +1 -0
  125. package/dist/inquiry/lib/inquiry.js +102 -0
  126. package/dist/inquiry/lib/inquiry.js.map +1 -0
  127. package/dist/inquiry/lib/kind-registry.d.ts +14 -0
  128. package/dist/inquiry/lib/kind-registry.d.ts.map +1 -0
  129. package/dist/inquiry/lib/kind-registry.js +24 -0
  130. package/dist/inquiry/lib/kind-registry.js.map +1 -0
  131. package/dist/inquiry/lib/policy.d.ts +19 -0
  132. package/dist/inquiry/lib/policy.d.ts.map +1 -0
  133. package/dist/inquiry/lib/policy.js +21 -0
  134. package/dist/inquiry/lib/policy.js.map +1 -0
  135. package/dist/inquiry/lib/recipient.d.ts +111 -0
  136. package/dist/inquiry/lib/recipient.d.ts.map +1 -0
  137. package/dist/inquiry/lib/recipient.js +64 -0
  138. package/dist/inquiry/lib/recipient.js.map +1 -0
  139. package/dist/inquiry/lib/workflow-verdict-evaluator.d.ts +15 -0
  140. package/dist/inquiry/lib/workflow-verdict-evaluator.d.ts.map +1 -0
  141. package/dist/inquiry/lib/workflow-verdict-evaluator.js +145 -0
  142. package/dist/inquiry/lib/workflow-verdict-evaluator.js.map +1 -0
  143. package/dist/org-database/index.d.ts +5 -0
  144. package/dist/org-database/index.d.ts.map +1 -0
  145. package/dist/org-database/index.js +21 -0
  146. package/dist/org-database/index.js.map +1 -0
  147. package/dist/org-database/lib/db-result-event.d.ts +24 -0
  148. package/dist/org-database/lib/db-result-event.d.ts.map +1 -0
  149. package/dist/org-database/lib/db-result-event.js +3 -0
  150. package/dist/org-database/lib/db-result-event.js.map +1 -0
  151. package/dist/org-database/lib/driver.d.ts +43 -0
  152. package/dist/org-database/lib/driver.d.ts.map +1 -0
  153. package/dist/org-database/lib/driver.js +3 -0
  154. package/dist/org-database/lib/driver.js.map +1 -0
  155. package/dist/org-database/lib/enums.d.ts +41 -0
  156. package/dist/org-database/lib/enums.d.ts.map +1 -0
  157. package/dist/org-database/lib/enums.js +51 -0
  158. package/dist/org-database/lib/enums.js.map +1 -0
  159. package/dist/org-database/lib/migration-runner.d.ts +15 -0
  160. package/dist/org-database/lib/migration-runner.d.ts.map +1 -0
  161. package/dist/org-database/lib/migration-runner.js +3 -0
  162. package/dist/org-database/lib/migration-runner.js.map +1 -0
  163. package/dist/project-kit/index.d.ts +2 -0
  164. package/dist/project-kit/index.d.ts.map +1 -0
  165. package/dist/project-kit/index.js +18 -0
  166. package/dist/project-kit/index.js.map +1 -0
  167. package/dist/project-kit/lib/project-kit.d.ts +63 -0
  168. package/dist/project-kit/lib/project-kit.d.ts.map +1 -0
  169. package/dist/project-kit/lib/project-kit.js +32 -0
  170. package/dist/project-kit/lib/project-kit.js.map +1 -0
  171. package/dist/provisioning/index.d.ts +2 -0
  172. package/dist/provisioning/index.d.ts.map +1 -0
  173. package/dist/provisioning/index.js +18 -0
  174. package/dist/provisioning/index.js.map +1 -0
  175. package/dist/provisioning/lib/provisioning.d.ts +256 -0
  176. package/dist/provisioning/lib/provisioning.d.ts.map +1 -0
  177. package/dist/provisioning/lib/provisioning.js +221 -0
  178. package/dist/provisioning/lib/provisioning.js.map +1 -0
  179. package/dist/worker-runtime/index.d.ts +6 -0
  180. package/dist/worker-runtime/index.d.ts.map +1 -0
  181. package/dist/worker-runtime/index.js +22 -0
  182. package/dist/worker-runtime/index.js.map +1 -0
  183. package/dist/worker-runtime/lib/capabilities.d.ts +22 -0
  184. package/dist/worker-runtime/lib/capabilities.d.ts.map +1 -0
  185. package/dist/worker-runtime/lib/capabilities.js +3 -0
  186. package/dist/worker-runtime/lib/capabilities.js.map +1 -0
  187. package/dist/worker-runtime/lib/enums.d.ts +10 -0
  188. package/dist/worker-runtime/lib/enums.d.ts.map +1 -0
  189. package/dist/worker-runtime/lib/enums.js +15 -0
  190. package/dist/worker-runtime/lib/enums.js.map +1 -0
  191. package/dist/worker-runtime/lib/messages.d.ts +33 -0
  192. package/dist/worker-runtime/lib/messages.d.ts.map +1 -0
  193. package/dist/worker-runtime/lib/messages.js +3 -0
  194. package/dist/worker-runtime/lib/messages.js.map +1 -0
  195. package/dist/worker-runtime/lib/runtime.d.ts +35 -0
  196. package/dist/worker-runtime/lib/runtime.d.ts.map +1 -0
  197. package/dist/worker-runtime/lib/runtime.js +3 -0
  198. package/dist/worker-runtime/lib/runtime.js.map +1 -0
  199. package/dist/worker-runtime/lib/schemas.d.ts +87 -0
  200. package/dist/worker-runtime/lib/schemas.d.ts.map +1 -0
  201. package/dist/worker-runtime/lib/schemas.js +57 -0
  202. package/dist/worker-runtime/lib/schemas.js.map +1 -0
  203. package/dist/workspace-storage/index.d.ts +4 -0
  204. package/dist/workspace-storage/index.d.ts.map +1 -0
  205. package/dist/workspace-storage/index.js +20 -0
  206. package/dist/workspace-storage/index.js.map +1 -0
  207. package/dist/workspace-storage/lib/enums.d.ts +34 -0
  208. package/dist/workspace-storage/lib/enums.d.ts.map +1 -0
  209. package/dist/workspace-storage/lib/enums.js +42 -0
  210. package/dist/workspace-storage/lib/enums.js.map +1 -0
  211. package/dist/workspace-storage/lib/schemas.d.ts +56 -0
  212. package/dist/workspace-storage/lib/schemas.d.ts.map +1 -0
  213. package/dist/workspace-storage/lib/schemas.js +59 -0
  214. package/dist/workspace-storage/lib/schemas.js.map +1 -0
  215. package/dist/workspace-storage/lib/types.d.ts +71 -0
  216. package/dist/workspace-storage/lib/types.d.ts.map +1 -0
  217. package/dist/workspace-storage/lib/types.js +3 -0
  218. package/dist/workspace-storage/lib/types.js.map +1 -0
  219. package/package.json +22 -153
  220. package/src/agent-composition/lib/composition-workspace.ts +1 -1
  221. package/src/agent-tool-inquiry/index.ts +16 -0
  222. package/src/agent-tool-inquiry/lib/agent-tool-inquiry.ts +82 -0
  223. package/src/agent-workspace/lib/workspace-spec.ts +1 -1
  224. package/src/app-runtime/index.ts +8 -0
  225. package/src/app-runtime/lib/app-client.ts +44 -0
  226. package/src/app-runtime/lib/app-lockfile.ts +54 -0
  227. package/src/app-runtime/lib/app.ts +84 -0
  228. package/src/app-runtime/lib/audience-policy.ts +87 -0
  229. package/src/app-runtime/lib/biome-install.ts +29 -0
  230. package/src/app-runtime/lib/branding-config.ts +54 -0
  231. package/src/app-runtime/lib/delegated-session.ts +69 -0
  232. package/src/app-runtime/lib/external-subject.ts +34 -0
  233. package/src/connector/index.ts +8 -0
  234. package/src/connector/lib/adapter-kind.ts +37 -0
  235. package/src/connector/lib/capability-refs.ts +29 -0
  236. package/src/connector/lib/capability.ts +38 -0
  237. package/src/connector/lib/credential-kind.ts +120 -0
  238. package/src/connector/lib/envelope-schema.ts +256 -0
  239. package/src/connector/lib/filter-expr-schema.ts +75 -0
  240. package/src/connector/lib/filter-expr-validate.ts +91 -0
  241. package/src/connector/lib/filter-expr.ts +208 -0
  242. package/src/connector/lib/onboarding-manifest.ts +167 -0
  243. package/src/document-render/index.ts +25 -0
  244. package/src/document-render/lib/measure-layout.ts +61 -0
  245. package/src/document-render/lib/render-enums.ts +49 -0
  246. package/src/document-render/lib/render-record.ts +38 -0
  247. package/src/document-render/lib/render-request.ts +16 -0
  248. package/src/document-render/lib/render-source.ts +44 -0
  249. package/src/document-render/lib/xema-prompt.ts +100 -0
  250. package/src/inquiry/index.ts +23 -0
  251. package/src/inquiry/lib/enums.ts +103 -0
  252. package/src/inquiry/lib/inquiry.ts +182 -0
  253. package/src/inquiry/lib/kind-registry.ts +57 -0
  254. package/src/inquiry/lib/policy.ts +27 -0
  255. package/src/inquiry/lib/recipient.ts +188 -0
  256. package/src/inquiry/lib/workflow-verdict-evaluator.ts +220 -0
  257. package/src/org-database/index.ts +4 -0
  258. package/src/org-database/lib/db-result-event.ts +59 -0
  259. package/src/org-database/lib/driver.ts +47 -0
  260. package/src/org-database/lib/enums.ts +51 -0
  261. package/src/org-database/lib/migration-runner.ts +17 -0
  262. package/src/project-kit/index.ts +17 -0
  263. package/src/project-kit/lib/project-kit.ts +227 -0
  264. package/src/provisioning/index.ts +17 -0
  265. package/src/provisioning/lib/provisioning.ts +499 -0
  266. package/src/worker-runtime/index.ts +14 -0
  267. package/src/worker-runtime/lib/capabilities.ts +58 -0
  268. package/src/worker-runtime/lib/enums.ts +33 -0
  269. package/src/worker-runtime/lib/messages.ts +49 -0
  270. package/src/worker-runtime/lib/runtime.ts +109 -0
  271. package/src/worker-runtime/lib/schemas.ts +72 -0
  272. package/src/workflow/lib/activity-outputs.ts +1 -1
  273. package/src/workflow/lib/compiled-run.ts +1 -1
  274. package/src/workflow/lib/compiled-workspace-manifest.ts +1 -1
  275. package/src/workflow/lib/model-ref.ts +1 -1
  276. package/src/workflow/lib/workspace-manifest-enums.ts +1 -1
  277. package/src/workspace-storage/index.ts +12 -0
  278. package/src/workspace-storage/lib/enums.ts +78 -0
  279. package/src/workspace-storage/lib/schemas.ts +75 -0
  280. package/src/workspace-storage/lib/types.ts +145 -0
@@ -0,0 +1,188 @@
1
+ import { z } from 'zod';
2
+
3
+ import { RecipientKind } from './enums';
4
+
5
+ /**
6
+ * Human recipient — a user identified by their identity-system subject.
7
+ * Resolution happens at the inquiry-creator layer (Decision Gate workflow
8
+ * or agent-tool-inquiry bridge); the contract carries the resolved string.
9
+ */
10
+ export const HumanRecipientTargetSchema = z.object({
11
+ userId: z.string().min(1),
12
+ });
13
+ export type HumanRecipientTarget = z.infer<typeof HumanRecipientTargetSchema>;
14
+
15
+ /**
16
+ * Agent recipient — a non-human decider invoked as a peer activity by the
17
+ * gate workflow or as an in-band call by the inquiry creator. `agentRef`
18
+ * resolves against the LLM agent registry; the runtime adapter (Platform)
19
+ * decides which agent runtime executes it.
20
+ *
21
+ * `skills` is the canonical extension point for attaching policy bundles
22
+ * (`@xemahq/kernel-contracts/skill`) to the reviewer agent — the same skill
23
+ * primitive a workflow agent step uses, mounted into the reviewer's
24
+ * workspace at `/workspace/.opencode/skills/<slug>/`. Each entry is a
25
+ * hierarchical skill slug (e.g. `gate-review/requirements-quality`).
26
+ * Replaces the legacy phase-config `gateReviewers[].perspective` /
27
+ * `scopeRules` block — the reviewer's per-phase policy now lives in a
28
+ * first-class Skill bundle that the composer mounts via the standard
29
+ * skill-resolution path.
30
+ *
31
+ * `invocationConfig` is opaque to this contract — passed through to the
32
+ * adapter unchanged.
33
+ */
34
+ export const AgentRecipientTargetSchema = z.object({
35
+ agentRef: z.string().min(1),
36
+ skills: z.array(z.string().min(1)).optional(),
37
+ invocationConfig: z.record(z.string(), z.unknown()).optional(),
38
+ });
39
+ export type AgentRecipientTarget = z.infer<typeof AgentRecipientTargetSchema>;
40
+
41
+ /**
42
+ * Endpoint recipient — an external HTTP endpoint that produces a verdict.
43
+ * `verdictMapper` extracts the verdict from the response body (JSONPath
44
+ * + schema). `authRef` resolves to a service-token credential at runtime.
45
+ */
46
+ export const EndpointVerdictMapperSchema = z.object({
47
+ /** JSONPath into the response body (e.g. `$.decision`). */
48
+ jsonPath: z.string().min(1),
49
+ /** Map of raw response values → typed verdict. */
50
+ verdictMap: z.record(z.string(), z.enum(['approve', 'reject', 'abstain'])),
51
+ });
52
+ export type EndpointVerdictMapper = z.infer<typeof EndpointVerdictMapperSchema>;
53
+
54
+ export const EndpointRecipientTargetSchema = z.object({
55
+ url: z.string().url(),
56
+ authRef: z.string().min(1),
57
+ verdictMapper: EndpointVerdictMapperSchema,
58
+ timeoutMs: z.number().int().positive().optional(),
59
+ });
60
+ export type EndpointRecipientTarget = z.infer<
61
+ typeof EndpointRecipientTargetSchema
62
+ >;
63
+
64
+ /**
65
+ * Identity-group recipient — an authoring-time alias for "every human
66
+ * member of this identity-system group, including descendants". The
67
+ * engine resolves it against the identity API at inquiry-create time and
68
+ * replaces it with N concrete `HUMAN` rows. It is therefore never seen
69
+ * on a persisted inquiry — only on the create request and in DSL.
70
+ *
71
+ * `allowEmpty` defaults to false: if the resolved member set is empty
72
+ * the engine fails inquiry creation with `INQUIRY_GROUP_EMPTY`. Set to
73
+ * true for groups that can legitimately be vacant (e.g. a fallback
74
+ * notification list).
75
+ */
76
+ export const IdentityGroupRecipientTargetSchema = z.object({
77
+ groupId: z.string().min(1),
78
+ allowEmpty: z.boolean().optional(),
79
+ });
80
+ export type IdentityGroupRecipientTarget = z.infer<
81
+ typeof IdentityGroupRecipientTargetSchema
82
+ >;
83
+
84
+ /**
85
+ * Verdict mapper applied to the child workflow's `outputs` map. Each
86
+ * outcome (`approve | reject | abstain`) is a JSON-path expression
87
+ * evaluated against `outputs`; the first matching outcome wins.
88
+ *
89
+ * Example:
90
+ * { approve: 'outputs.compliant === true',
91
+ * reject: 'outputs.compliant === false' }
92
+ *
93
+ * Shape kept intentionally narrow — full expression engines belong in
94
+ * the runtime activity, not in the contract.
95
+ */
96
+ export const WorkflowVerdictMapperSchema = z.object({
97
+ approve: z.string().min(1).optional(),
98
+ reject: z.string().min(1).optional(),
99
+ abstain: z.string().min(1).optional(),
100
+ });
101
+ export type WorkflowVerdictMapper = z.infer<
102
+ typeof WorkflowVerdictMapperSchema
103
+ >;
104
+
105
+ /**
106
+ * Workflow recipient — dispatch a child workflow as a non-human
107
+ * responder. The engine starts the workflow with `inputs`, awaits
108
+ * termination, and maps `outputs` to `{ verdict, payload }` using
109
+ * `verdictMapper`. From the inquiry's perspective the reply is
110
+ * indistinguishable from a human submission.
111
+ *
112
+ * Recursion is bounded by the engine's responder-chain check: if the
113
+ * dispatched slug is already on the chain, creation fails with
114
+ * `INQUIRY_RESPONDER_CYCLE`.
115
+ */
116
+ export const WorkflowRecipientTargetSchema = z.object({
117
+ workflowSlug: z.string().min(1),
118
+ inputs: z.record(z.string(), z.unknown()).optional(),
119
+ verdictMapper: WorkflowVerdictMapperSchema.optional(),
120
+ });
121
+ export type WorkflowRecipientTarget = z.infer<
122
+ typeof WorkflowRecipientTargetSchema
123
+ >;
124
+
125
+ /**
126
+ * Fields shared by every recipient variant. Authoring-time orthogonal
127
+ * to `kind` — they describe *how the recipient participates in policy
128
+ * evaluation*, not who they are.
129
+ *
130
+ * `mandatory` (defaults true at the engine boundary): when false the
131
+ * recipient's verdict is collected for context but does NOT
132
+ * participate in policy evaluation. Existing decision-gate call
133
+ * sites omit the field — the engine treats `undefined` as `true` so
134
+ * behavior is unchanged. Used by `xema/review@v3` to mark advisory
135
+ * reviewers that contribute findings without veto power.
136
+ *
137
+ * Schema-side the field is left `.optional()` (not `.default(true)`)
138
+ * so the TypeScript type stays `mandatory?: boolean` for callers,
139
+ * while the persistence layer (DB default true) and the engine's
140
+ * `expandGroupRecipients` (`r.mandatory ?? true`) materialize the
141
+ * default exactly once.
142
+ *
143
+ * `agentMaxIterations`: review-loop hint — max number of times this
144
+ * AGENT or WORKFLOW responder may reject before the loop demotes it
145
+ * to advisory. Ignored outside of `xema/review@v3`; not persisted on
146
+ * the recipient row (the review workflow tracks counters in its own
147
+ * state).
148
+ */
149
+ export const RecipientCommonSchema = z.object({
150
+ mandatory: z.boolean().optional(),
151
+ agentMaxIterations: z.number().int().positive().optional(),
152
+ });
153
+ export type RecipientCommon = z.infer<typeof RecipientCommonSchema>;
154
+
155
+ /**
156
+ * Discriminated recipient. Adding a new kind is a one-line enum extension
157
+ * + a new schema variant; existing recipients are unaffected.
158
+ *
159
+ * The result is the intersection of the discriminated union (kind+target)
160
+ * and `RecipientCommonSchema` so every variant carries `mandatory` /
161
+ * `agentMaxIterations` without duplicating those declarations per kind.
162
+ */
163
+ export const RecipientSchema = z.intersection(
164
+ z.discriminatedUnion('kind', [
165
+ z.object({
166
+ kind: z.literal(RecipientKind.HUMAN),
167
+ target: HumanRecipientTargetSchema,
168
+ }),
169
+ z.object({
170
+ kind: z.literal(RecipientKind.AGENT),
171
+ target: AgentRecipientTargetSchema,
172
+ }),
173
+ z.object({
174
+ kind: z.literal(RecipientKind.ENDPOINT),
175
+ target: EndpointRecipientTargetSchema,
176
+ }),
177
+ z.object({
178
+ kind: z.literal(RecipientKind.IDENTITY_GROUP),
179
+ target: IdentityGroupRecipientTargetSchema,
180
+ }),
181
+ z.object({
182
+ kind: z.literal(RecipientKind.WORKFLOW),
183
+ target: WorkflowRecipientTargetSchema,
184
+ }),
185
+ ]),
186
+ RecipientCommonSchema,
187
+ );
188
+ export type Recipient = z.infer<typeof RecipientSchema>;
@@ -0,0 +1,220 @@
1
+ import type { WorkflowVerdictMapper } from './recipient';
2
+
3
+ /**
4
+ * Bounded grammar for `WorkflowVerdictMapper` expressions. The runtime
5
+ * dispatcher (worker-side) and the engine validator (inquiry-create
6
+ * boundary) share this implementation so authors hit identical errors at
7
+ * both ends.
8
+ *
9
+ * Supported forms:
10
+ * `outputs` → truthy when value is non-null / non-undefined / non-false / non-empty-string
11
+ * `outputs.<key>(.<key>)*` → same truthy check on a nested field
12
+ * `outputs.<path> === <literal>` → strict equality
13
+ * `outputs.<path> !== <literal>` → strict inequality
14
+ *
15
+ * Literals: `true`, `false`, `null`, `"<string>"`, `<number>`. Strings
16
+ * support escaped backslash + double-quote (`\\` and `\"`); other escape
17
+ * sequences are passed through verbatim. Floats use a leading digit
18
+ * (`0.5`, not `.5`).
19
+ *
20
+ * Anything outside this grammar fails parsing. Callers convert parse
21
+ * failure into a typed error (engine: 400 INQUIRY_VERDICT_MAPPER_INVALID;
22
+ * worker: ABSTAIN with `verdictmapper_unparseable:<expression>`).
23
+ *
24
+ * Why so narrow: a permissive grammar (full JS, JSONPath filters) would
25
+ * push expression evaluation into a runtime that can throw on arbitrary
26
+ * inputs and complicate sandboxing. The supported set covers the
27
+ * documented examples (`outputs.compliant === true`) and forces authors
28
+ * to do any structural reshaping inside the responder workflow's
29
+ * `outputs:` block — where it belongs.
30
+ */
31
+
32
+ const PATH_SEGMENT = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
33
+
34
+ export type CompiledWorkflowVerdictExpression = (
35
+ outputs: Readonly<Record<string, unknown>>,
36
+ ) => boolean;
37
+
38
+ export interface CompiledWorkflowVerdictMapper {
39
+ readonly approve?: CompiledWorkflowVerdictExpression;
40
+ readonly reject?: CompiledWorkflowVerdictExpression;
41
+ readonly abstain?: CompiledWorkflowVerdictExpression;
42
+ }
43
+
44
+ export class WorkflowVerdictMapperParseError extends Error {
45
+ constructor(
46
+ public readonly outcome: 'approve' | 'reject' | 'abstain',
47
+ public readonly expression: string,
48
+ detail: string,
49
+ ) {
50
+ super(
51
+ `WorkflowVerdictMapper.${outcome} expression '${expression}' is invalid: ${detail}`,
52
+ );
53
+ this.name = 'WorkflowVerdictMapperParseError';
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Parse + compile every defined branch in the mapper. Throws
59
+ * `WorkflowVerdictMapperParseError` on the first invalid expression so
60
+ * authors fix one issue at a time with a clear diagnostic.
61
+ */
62
+ export function compileWorkflowVerdictMapper(
63
+ mapper: WorkflowVerdictMapper,
64
+ ): CompiledWorkflowVerdictMapper {
65
+ return {
66
+ ...(mapper.approve !== undefined && {
67
+ approve: compileExpression('approve', mapper.approve),
68
+ }),
69
+ ...(mapper.reject !== undefined && {
70
+ reject: compileExpression('reject', mapper.reject),
71
+ }),
72
+ ...(mapper.abstain !== undefined && {
73
+ abstain: compileExpression('abstain', mapper.abstain),
74
+ }),
75
+ };
76
+ }
77
+
78
+ /**
79
+ * Apply a compiled mapper against the responder workflow's flattened
80
+ * outputs. Returns the first matching outcome (in `approve → reject →
81
+ * abstain` order) or `null` when no branch matched.
82
+ */
83
+ export function evaluateCompiledWorkflowVerdictMapper(
84
+ mapper: CompiledWorkflowVerdictMapper,
85
+ outputs: Readonly<Record<string, unknown>>,
86
+ ): 'approve' | 'reject' | 'abstain' | null {
87
+ if (mapper.approve && mapper.approve(outputs)) {return 'approve';}
88
+ if (mapper.reject && mapper.reject(outputs)) {return 'reject';}
89
+ if (mapper.abstain && mapper.abstain(outputs)) {return 'abstain';}
90
+ return null;
91
+ }
92
+
93
+ function compileExpression(
94
+ outcome: 'approve' | 'reject' | 'abstain',
95
+ raw: string,
96
+ ): CompiledWorkflowVerdictExpression {
97
+ const expression = raw.trim();
98
+ if (expression.length === 0) {
99
+ throw new WorkflowVerdictMapperParseError(outcome, raw, 'expression is empty');
100
+ }
101
+ const equality = expression.match(/^(.+?)\s+(===|!==)\s+(.+)$/);
102
+ if (equality) {
103
+ const [, lhsRaw, op, rhsRaw] = equality;
104
+ const path = parseOutputsPath(outcome, raw, lhsRaw!);
105
+ const literal = parseLiteral(outcome, raw, rhsRaw!);
106
+ return (outputs) => {
107
+ const value = readPath(outputs, path);
108
+ return op === '===' ? value === literal : value !== literal;
109
+ };
110
+ }
111
+ const path = parseOutputsPath(outcome, raw, expression);
112
+ return (outputs) => isTruthy(readPath(outputs, path));
113
+ }
114
+
115
+ function parseOutputsPath(
116
+ outcome: 'approve' | 'reject' | 'abstain',
117
+ raw: string,
118
+ cursor: string,
119
+ ): readonly string[] {
120
+ const trimmed = cursor.trim();
121
+ if (trimmed === 'outputs') {return [];}
122
+ if (!trimmed.startsWith('outputs.')) {
123
+ throw new WorkflowVerdictMapperParseError(
124
+ outcome,
125
+ raw,
126
+ `expected 'outputs' or 'outputs.<path>' (got '${trimmed}')`,
127
+ );
128
+ }
129
+ const segments = trimmed.slice('outputs.'.length).split('.');
130
+ for (const seg of segments) {
131
+ if (!PATH_SEGMENT.test(seg)) {
132
+ throw new WorkflowVerdictMapperParseError(
133
+ outcome,
134
+ raw,
135
+ `'${seg}' is not a valid identifier (segments must match ${PATH_SEGMENT.source})`,
136
+ );
137
+ }
138
+ }
139
+ return segments;
140
+ }
141
+
142
+ function parseLiteral(
143
+ outcome: 'approve' | 'reject' | 'abstain',
144
+ raw: string,
145
+ cursor: string,
146
+ ): string | number | boolean | null {
147
+ const trimmed = cursor.trim();
148
+ if (trimmed === 'true') {return true;}
149
+ if (trimmed === 'false') {return false;}
150
+ if (trimmed === 'null') {return null;}
151
+ if (trimmed.startsWith('"') && trimmed.endsWith('"') && trimmed.length >= 2) {
152
+ return parseStringLiteral(outcome, raw, trimmed);
153
+ }
154
+ // Numbers: integers + simple floats. No leading dot, no exponent (yet);
155
+ // expand the grammar in a follow-up if real authors need it.
156
+ if (/^-?[0-9]+(\.[0-9]+)?$/.test(trimmed)) {
157
+ return Number(trimmed);
158
+ }
159
+ throw new WorkflowVerdictMapperParseError(
160
+ outcome,
161
+ raw,
162
+ `right-hand side '${trimmed}' is not a supported literal (true | false | null | "string" | number)`,
163
+ );
164
+ }
165
+
166
+ function parseStringLiteral(
167
+ outcome: 'approve' | 'reject' | 'abstain',
168
+ raw: string,
169
+ literal: string,
170
+ ): string {
171
+ const inner = literal.slice(1, -1);
172
+ let out = '';
173
+ for (let i = 0; i < inner.length; i++) {
174
+ const ch = inner[i]!;
175
+ if (ch === '\\') {
176
+ const next = inner[i + 1];
177
+ if (next === '\\' || next === '"') {
178
+ out += next;
179
+ i++;
180
+ continue;
181
+ }
182
+ throw new WorkflowVerdictMapperParseError(
183
+ outcome,
184
+ raw,
185
+ `unsupported escape in string literal — only \\\\ and \\" are allowed`,
186
+ );
187
+ }
188
+ if (ch === '"') {
189
+ throw new WorkflowVerdictMapperParseError(
190
+ outcome,
191
+ raw,
192
+ `unescaped double-quote inside string literal`,
193
+ );
194
+ }
195
+ out += ch;
196
+ }
197
+ return out;
198
+ }
199
+
200
+ function readPath(
201
+ source: Readonly<Record<string, unknown>>,
202
+ path: readonly string[],
203
+ ): unknown {
204
+ let cursor: unknown = source;
205
+ for (const segment of path) {
206
+ if (cursor === null || cursor === undefined) {return undefined;}
207
+ if (typeof cursor !== 'object') {return undefined;}
208
+ cursor = (cursor as Record<string, unknown>)[segment];
209
+ }
210
+ return cursor;
211
+ }
212
+
213
+ function isTruthy(value: unknown): boolean {
214
+ if (value === null || value === undefined) {return false;}
215
+ if (typeof value === 'boolean') {return value;}
216
+ if (typeof value === 'string') {return value.length > 0;}
217
+ if (typeof value === 'number') {return value !== 0 && !Number.isNaN(value);}
218
+ // Objects (including arrays) are truthy.
219
+ return true;
220
+ }
@@ -0,0 +1,4 @@
1
+ export * from './lib/enums';
2
+ export * from './lib/driver';
3
+ export * from './lib/migration-runner';
4
+ export * from './lib/db-result-event';
@@ -0,0 +1,59 @@
1
+ import type { DbMutationKind } from './enums';
2
+
3
+ /**
4
+ * Column metadata for a result set row returned by the database explorer.
5
+ *
6
+ * Field semantics:
7
+ * - `name` — column alias as it appears in the result set
8
+ * - `typeOid` — Postgres pg_type OID (closed across a given server version)
9
+ * - `typeName` — human-readable Postgres type name (e.g. `int4`, `text`,
10
+ * `timestamptz`). Sourced from `information_schema` /
11
+ * `pg_type.typname`; used for UI type chips.
12
+ * - `nullable` — `true` when the column is nullable. For ad-hoc query
13
+ * columns where nullability cannot be determined from the
14
+ * statement alone, the producer SHOULD set `true`
15
+ * (conservative default).
16
+ * - `isPrimaryKey` — `true` only for table-column listings, undefined
17
+ * for ad-hoc SELECT projections.
18
+ * - `foreignKeyTarget` — `"<schema>.<table>.<column>"` reference for FK
19
+ * columns; undefined when no FK exists or the column
20
+ * is an ad-hoc projection.
21
+ */
22
+ export interface DbColumnMeta {
23
+ readonly name: string;
24
+ readonly typeOid: number;
25
+ readonly typeName: string;
26
+ readonly nullable: boolean;
27
+ readonly isPrimaryKey?: boolean;
28
+ readonly foreignKeyTarget?: string;
29
+ }
30
+
31
+ /**
32
+ * Surface event payload emitted when the database explorer executes a SQL
33
+ * statement on behalf of an agent tool call. Mirrors plan §12.4 verbatim.
34
+ *
35
+ * `rows` carries the actual row data — it MUST go to the frontend only and
36
+ * MUST never be passed back into LLM context. Producers route it through
37
+ * the agent-session SSE channel (in H5+) or return it inline to the
38
+ * caller (in H1, when no SSE bridge exists yet).
39
+ *
40
+ * `statement` is the SQL string the agent supplied. It is shown in the UI
41
+ * as a reference for the user; it is NOT a secret. Audit logs hash the
42
+ * statement separately — never log it verbatim.
43
+ */
44
+ export interface DbResultSurfaceEvent {
45
+ readonly type: 'db.result';
46
+ /** Stable per tool call so the frontend can update the same widget on retry. */
47
+ readonly surfaceId: string;
48
+ readonly databaseId: string;
49
+ readonly schemaName: string;
50
+ readonly statement: string;
51
+ readonly columns: readonly DbColumnMeta[];
52
+ readonly rows: readonly unknown[][];
53
+ readonly rowCount: number;
54
+ readonly truncated: boolean;
55
+ readonly durationMs: number;
56
+ /** Present only on mutate results — discriminates the wire shape. */
57
+ readonly mutationKind?: DbMutationKind;
58
+ readonly affectedRows?: number;
59
+ }
@@ -0,0 +1,47 @@
1
+ import type { DbDriverKind } from './enums';
2
+
3
+ export interface ProvisionInput {
4
+ orgId: string;
5
+ databaseName: string;
6
+ }
7
+
8
+ export interface EnsureSchemaInput {
9
+ databaseName: string;
10
+ schemaName: string;
11
+ rwRoleName: string;
12
+ roRoleName: string;
13
+ }
14
+
15
+ export interface DropSchemaInput {
16
+ databaseName: string;
17
+ schemaName: string;
18
+ rwRoleName: string;
19
+ roRoleName: string;
20
+ }
21
+
22
+ export interface MintConnectionInput {
23
+ databaseName: string;
24
+ schemaName: string;
25
+ roleName: string;
26
+ ttlSeconds: number;
27
+ }
28
+
29
+ export interface ConnectionGrant {
30
+ host: string;
31
+ port: number;
32
+ database: string;
33
+ schema: string;
34
+ user: string;
35
+ password: string;
36
+ expiresAt: Date;
37
+ }
38
+
39
+ export interface DatabaseDriver {
40
+ readonly kind: DbDriverKind;
41
+
42
+ provisionOrgDatabase(input: ProvisionInput): Promise<{ databaseName: string }>;
43
+ ensureSchema(input: EnsureSchemaInput): Promise<void>;
44
+ dropSchema(input: DropSchemaInput): Promise<void>;
45
+ dropOrgDatabase(databaseName: string): Promise<void>;
46
+ mintConnection(input: MintConnectionInput): Promise<ConnectionGrant>;
47
+ }
@@ -0,0 +1,51 @@
1
+ export enum DbDriverKind {
2
+ Postgres = 'postgres',
3
+ Mongo = 'mongo',
4
+ Weaviate = 'weaviate',
5
+ }
6
+
7
+ export enum DbPoolStatus {
8
+ Active = 'active',
9
+ Draining = 'draining',
10
+ Decommissioned = 'decommissioned',
11
+ }
12
+
13
+ export enum OrgDatabaseStatus {
14
+ Provisioning = 'provisioning',
15
+ Active = 'active',
16
+ Migrating = 'migrating',
17
+ Failed = 'failed',
18
+ Archived = 'archived',
19
+ }
20
+
21
+ export enum OrgDatabasePurpose {
22
+ Biome = 'biome',
23
+ AppDev = 'app_dev',
24
+ AppProd = 'app_prod',
25
+ System = 'system',
26
+ }
27
+
28
+ export enum MigrationRunnerKind {
29
+ Prisma = 'prisma',
30
+ Drizzle = 'drizzle',
31
+ Flyway = 'flyway',
32
+ RawSql = 'raw_sql',
33
+ }
34
+
35
+ export enum MigrationStatus {
36
+ Pending = 'pending',
37
+ Running = 'running',
38
+ Succeeded = 'succeeded',
39
+ Failed = 'failed',
40
+ }
41
+
42
+ /**
43
+ * The kind of single-statement DML executed via the explorer `/mutate`
44
+ * endpoint. Closed domain — the SQL validator rejects everything else
45
+ * (DDL, multi-statement, transactional control) at parse time.
46
+ */
47
+ export enum DbMutationKind {
48
+ Insert = 'insert',
49
+ Update = 'update',
50
+ Delete = 'delete',
51
+ }
@@ -0,0 +1,17 @@
1
+ import type { MigrationRunnerKind } from './enums';
2
+
3
+ export interface MigrationRunInput {
4
+ connectionUrl: string;
5
+ workspaceDir: string;
6
+ env: Record<string, string>;
7
+ }
8
+
9
+ export interface MigrationRunResult {
10
+ exitCode: number;
11
+ output: string;
12
+ }
13
+
14
+ export interface MigrationRunner {
15
+ readonly kind: MigrationRunnerKind;
16
+ run(input: MigrationRunInput): Promise<MigrationRunResult>;
17
+ }
@@ -0,0 +1,17 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════
2
+ // @xemahq/project-kit-contracts — Project Kit wire contracts.
3
+ //
4
+ // Pure types + enums for the "Project Kit" concept (reusable units installed
5
+ // into a project repo at session start). Zero runtime deps.
6
+ //
7
+ // A FOCUSED package on purpose: the catalog DTOs in `llm-registry-api` and
8
+ // `webapp-studio-api` expose these enums via `@ApiProperty({ enum })`, and the
9
+ // @nestjs/swagger CLI plugin bakes a `require()` to each enum's declaration
10
+ // into the OpenAPI metadata factory. That require only resolves cleanly when
11
+ // the package is NOT physically nested under another (`platform-common` is, so
12
+ // enums living there produced an unresolvable nested specifier). Keeping these
13
+ // contracts in their own leaf package — depended on only by the consuming
14
+ // services, never transitively — guarantees a clean top-level resolution.
15
+ // ═══════════════════════════════════════════════════════════════════════════
16
+
17
+ export * from './lib/project-kit';