gatewaysdk 0.3.2__py3-none-any.whl

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 (376) hide show
  1. gatewaysdk/__init__.py +540 -0
  2. gatewaysdk/adapter/__init__.py +15 -0
  3. gatewaysdk/adapter/base.py +94 -0
  4. gatewaysdk/adapter/messages.py +270 -0
  5. gatewaysdk/adapter/triplet.py +1026 -0
  6. gatewaysdk/algorithm/__init__.py +39 -0
  7. gatewaysdk/algorithm/apo/__init__.py +5 -0
  8. gatewaysdk/algorithm/apo/apo.py +898 -0
  9. gatewaysdk/algorithm/apo/prompts/apply_edit_variant01.poml +22 -0
  10. gatewaysdk/algorithm/apo/prompts/apply_edit_variant02.poml +18 -0
  11. gatewaysdk/algorithm/apo/prompts/text_gradient_variant01.poml +18 -0
  12. gatewaysdk/algorithm/apo/prompts/text_gradient_variant02.poml +16 -0
  13. gatewaysdk/algorithm/apo/prompts/text_gradient_variant03.poml +107 -0
  14. gatewaysdk/algorithm/base.py +262 -0
  15. gatewaysdk/algorithm/decorator.py +264 -0
  16. gatewaysdk/algorithm/evals/__init__.py +7 -0
  17. gatewaysdk/algorithm/evals/evals.py +217 -0
  18. gatewaysdk/algorithm/fast.py +250 -0
  19. gatewaysdk/algorithm/gepa/__init__.py +61 -0
  20. gatewaysdk/algorithm/gepa/adapter.py +495 -0
  21. gatewaysdk/algorithm/gepa/gepa.py +570 -0
  22. gatewaysdk/algorithm/gepa/lib/__init__.py +18 -0
  23. gatewaysdk/algorithm/gepa/lib/adapters/README.md +12 -0
  24. gatewaysdk/algorithm/gepa/lib/adapters/__init__.py +0 -0
  25. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/README.md +341 -0
  26. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/__init__.py +1 -0
  27. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/anymaths_adapter.py +174 -0
  28. gatewaysdk/algorithm/gepa/lib/adapters/anymaths_adapter/requirements.txt +1 -0
  29. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/README.md +0 -0
  30. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/__init__.py +0 -0
  31. gatewaysdk/algorithm/gepa/lib/adapters/default_adapter/default_adapter.py +209 -0
  32. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/README.md +7 -0
  33. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/__init__.py +0 -0
  34. gatewaysdk/algorithm/gepa/lib/adapters/dspy_adapter/dspy_adapter.py +307 -0
  35. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/README.md +99 -0
  36. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/dspy_program_proposal_signature.py +137 -0
  37. gatewaysdk/algorithm/gepa/lib/adapters/dspy_full_program_adapter/full_program_adapter.py +268 -0
  38. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/GEPA_RAG.md +621 -0
  39. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/__init__.py +56 -0
  40. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/evaluation_metrics.py +226 -0
  41. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/generic_rag_adapter.py +496 -0
  42. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/rag_pipeline.py +238 -0
  43. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_store_interface.py +212 -0
  44. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/__init__.py +2 -0
  45. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/chroma_store.py +196 -0
  46. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/lancedb_store.py +422 -0
  47. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/milvus_store.py +409 -0
  48. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/qdrant_store.py +368 -0
  49. gatewaysdk/algorithm/gepa/lib/adapters/generic_rag_adapter/vector_stores/weaviate_store.py +418 -0
  50. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/README.md +552 -0
  51. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/__init__.py +37 -0
  52. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_adapter.py +699 -0
  53. gatewaysdk/algorithm/gepa/lib/adapters/mcp_adapter/mcp_client.py +364 -0
  54. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/README.md +9 -0
  55. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/__init__.py +0 -0
  56. gatewaysdk/algorithm/gepa/lib/adapters/terminal_bench_adapter/terminal_bench_adapter.py +217 -0
  57. gatewaysdk/algorithm/gepa/lib/api.py +382 -0
  58. gatewaysdk/algorithm/gepa/lib/core/__init__.py +0 -0
  59. gatewaysdk/algorithm/gepa/lib/core/adapter.py +180 -0
  60. gatewaysdk/algorithm/gepa/lib/core/data_loader.py +74 -0
  61. gatewaysdk/algorithm/gepa/lib/core/engine.py +379 -0
  62. gatewaysdk/algorithm/gepa/lib/core/result.py +233 -0
  63. gatewaysdk/algorithm/gepa/lib/core/state.py +636 -0
  64. gatewaysdk/algorithm/gepa/lib/examples/__init__.py +0 -0
  65. gatewaysdk/algorithm/gepa/lib/examples/aime.py +24 -0
  66. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/eval_default.py +111 -0
  67. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/instruction_prompt.txt +9 -0
  68. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/prompt-templates/optimal_prompt.txt +24 -0
  69. gatewaysdk/algorithm/gepa/lib/examples/anymaths-bench/train_anymaths.py +177 -0
  70. gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/arc_agi.ipynb +25705 -0
  71. gatewaysdk/algorithm/gepa/lib/examples/dspy_full_program_evolution/example.ipynb +348 -0
  72. gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/__init__.py +4 -0
  73. gatewaysdk/algorithm/gepa/lib/examples/mcp_adapter/mcp_optimization_example.py +456 -0
  74. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/RAG_GUIDE.md +613 -0
  75. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/__init__.py +9 -0
  76. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/rag_optimization.py +820 -0
  77. gatewaysdk/algorithm/gepa/lib/examples/rag_adapter/requirements-rag.txt +29 -0
  78. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/instruction_prompt.txt +16 -0
  79. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/prompt-templates/terminus.txt +9 -0
  80. gatewaysdk/algorithm/gepa/lib/examples/terminal-bench/train_terminus.py +161 -0
  81. gatewaysdk/algorithm/gepa/lib/gepa_utils.py +117 -0
  82. gatewaysdk/algorithm/gepa/lib/logging/__init__.py +0 -0
  83. gatewaysdk/algorithm/gepa/lib/logging/experiment_tracker.py +187 -0
  84. gatewaysdk/algorithm/gepa/lib/logging/logger.py +75 -0
  85. gatewaysdk/algorithm/gepa/lib/logging/utils.py +103 -0
  86. gatewaysdk/algorithm/gepa/lib/proposer/__init__.py +0 -0
  87. gatewaysdk/algorithm/gepa/lib/proposer/base.py +31 -0
  88. gatewaysdk/algorithm/gepa/lib/proposer/merge.py +357 -0
  89. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/__init__.py +0 -0
  90. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/base.py +49 -0
  91. gatewaysdk/algorithm/gepa/lib/proposer/reflective_mutation/reflective_mutation.py +176 -0
  92. gatewaysdk/algorithm/gepa/lib/py.typed +0 -0
  93. gatewaysdk/algorithm/gepa/lib/strategies/__init__.py +0 -0
  94. gatewaysdk/algorithm/gepa/lib/strategies/batch_sampler.py +77 -0
  95. gatewaysdk/algorithm/gepa/lib/strategies/candidate_selector.py +50 -0
  96. gatewaysdk/algorithm/gepa/lib/strategies/component_selector.py +36 -0
  97. gatewaysdk/algorithm/gepa/lib/strategies/eval_policy.py +64 -0
  98. gatewaysdk/algorithm/gepa/lib/strategies/instruction_proposal.py +126 -0
  99. gatewaysdk/algorithm/gepa/lib/utils/__init__.py +10 -0
  100. gatewaysdk/algorithm/gepa/lib/utils/stop_condition.py +196 -0
  101. gatewaysdk/algorithm/gepa/tracing.py +105 -0
  102. gatewaysdk/algorithm/utils.py +177 -0
  103. gatewaysdk/algorithm/verl/__init__.py +5 -0
  104. gatewaysdk/algorithm/verl/interface.py +202 -0
  105. gatewaysdk/automations.py +111 -0
  106. gatewaysdk/benchmark_hub/README.md +88 -0
  107. gatewaysdk/benchmark_hub/__init__.py +119 -0
  108. gatewaysdk/benchmark_hub/_archive.py +189 -0
  109. gatewaysdk/benchmark_hub/_tar.py +6 -0
  110. gatewaysdk/benchmark_hub/client.py +992 -0
  111. gatewaysdk/benchmark_hub/dispatch_shard.py +34 -0
  112. gatewaysdk/benchmark_hub/eval_config.py +20 -0
  113. gatewaysdk/benchmark_hub/evals.py +351 -0
  114. gatewaysdk/benchmark_hub/harbor_adapter.py +673 -0
  115. gatewaysdk/benchmark_hub/path_utils.py +81 -0
  116. gatewaysdk/benchmark_hub/save_utils.py +101 -0
  117. gatewaysdk/benchmark_hub/verifiers_adapter.py +327 -0
  118. gatewaysdk/benchmark_hub/versioning.py +72 -0
  119. gatewaysdk/build.py +515 -0
  120. gatewaysdk/cli/__init__.py +58 -0
  121. gatewaysdk/cli/agent_runner.py +132 -0
  122. gatewaysdk/cli/http_client.py +115 -0
  123. gatewaysdk/cli/platform.py +4086 -0
  124. gatewaysdk/cli/prometheus.py +115 -0
  125. gatewaysdk/cli/release_gate.py +215 -0
  126. gatewaysdk/cli/store.py +131 -0
  127. gatewaysdk/cli/vllm.py +29 -0
  128. gatewaysdk/client.py +406 -0
  129. gatewaysdk/config.py +348 -0
  130. gatewaysdk/connectors/__init__.py +25 -0
  131. gatewaysdk/connectors/client.py +203 -0
  132. gatewaysdk/connectors/skill.py +25 -0
  133. gatewaysdk/connectors/template.py +106 -0
  134. gatewaysdk/context.py +606 -0
  135. gatewaysdk/emitter/__init__.py +43 -0
  136. gatewaysdk/emitter/annotation.py +370 -0
  137. gatewaysdk/emitter/exception.py +54 -0
  138. gatewaysdk/emitter/message.py +61 -0
  139. gatewaysdk/emitter/object.py +117 -0
  140. gatewaysdk/emitter/reward.py +320 -0
  141. gatewaysdk/env_var.py +156 -0
  142. gatewaysdk/environment/__init__.py +108 -0
  143. gatewaysdk/environment/_bundle.py +281 -0
  144. gatewaysdk/environment/_harbor.py +276 -0
  145. gatewaysdk/environment/_materialize.py +97 -0
  146. gatewaysdk/environment/_tar.py +33 -0
  147. gatewaysdk/environment/_world.py +346 -0
  148. gatewaysdk/environment/core.py +527 -0
  149. gatewaysdk/environment/errors.py +58 -0
  150. gatewaysdk/environment/runtime.py +150 -0
  151. gatewaysdk/environment/schema/__init__.py +35 -0
  152. gatewaysdk/environment/schema/__main__.py +225 -0
  153. gatewaysdk/environment/schema/_slack_fidelity.py +116 -0
  154. gatewaysdk/environment/schema/_slack_scenario.py +183 -0
  155. gatewaysdk/environment/schema/api.py +1628 -0
  156. gatewaysdk/environment/schema/batch.py +755 -0
  157. gatewaysdk/environment/schema/compiler.py +615 -0
  158. gatewaysdk/environment/schema/conform.py +428 -0
  159. gatewaysdk/environment/schema/connector.py +777 -0
  160. gatewaysdk/environment/schema/connectors/apple-business-manager/handlers.py +17 -0
  161. gatewaysdk/environment/schema/connectors/apple-business-manager/parity.json +28 -0
  162. gatewaysdk/environment/schema/connectors/apple-business-manager/provenance.json +233 -0
  163. gatewaysdk/environment/schema/connectors/apple-business-manager/scope.toml +112 -0
  164. gatewaysdk/environment/schema/connectors/apple-business-manager/world.json +1380 -0
  165. gatewaysdk/environment/schema/connectors/base.json +28 -0
  166. gatewaysdk/environment/schema/connectors/custom/handlers.py +18 -0
  167. gatewaysdk/environment/schema/connectors/custom/world.json +123 -0
  168. gatewaysdk/environment/schema/connectors/github/handlers.py +81 -0
  169. gatewaysdk/environment/schema/connectors/github/parity.json +37 -0
  170. gatewaysdk/environment/schema/connectors/github/provenance.json +134 -0
  171. gatewaysdk/environment/schema/connectors/github/scope.toml +158 -0
  172. gatewaysdk/environment/schema/connectors/github/world.json +5869 -0
  173. gatewaysdk/environment/schema/connectors/google-calendar/handlers.py +23 -0
  174. gatewaysdk/environment/schema/connectors/google-calendar/world.json +209 -0
  175. gatewaysdk/environment/schema/connectors/google-drive/handlers.py +18 -0
  176. gatewaysdk/environment/schema/connectors/google-drive/world.json +286 -0
  177. gatewaysdk/environment/schema/connectors/jamf/handlers.py +34 -0
  178. gatewaysdk/environment/schema/connectors/jamf/parity.json +49 -0
  179. gatewaysdk/environment/schema/connectors/jamf/provenance.json +181 -0
  180. gatewaysdk/environment/schema/connectors/jamf/scope.toml +128 -0
  181. gatewaysdk/environment/schema/connectors/jamf/world.json +2218 -0
  182. gatewaysdk/environment/schema/connectors/jira/handlers.py +28 -0
  183. gatewaysdk/environment/schema/connectors/jira/world.json +389 -0
  184. gatewaysdk/environment/schema/connectors/kandji/handlers.py +38 -0
  185. gatewaysdk/environment/schema/connectors/kandji/parity.json +29 -0
  186. gatewaysdk/environment/schema/connectors/kandji/provenance.json +152 -0
  187. gatewaysdk/environment/schema/connectors/kandji/scope.toml +120 -0
  188. gatewaysdk/environment/schema/connectors/kandji/world.json +765 -0
  189. gatewaysdk/environment/schema/connectors/linear/handlers.py +20 -0
  190. gatewaysdk/environment/schema/connectors/linear/world.json +363 -0
  191. gatewaysdk/environment/schema/connectors/microsoft-teams/fidelity.json +45 -0
  192. gatewaysdk/environment/schema/connectors/microsoft-teams/handlers.py +1 -0
  193. gatewaysdk/environment/schema/connectors/microsoft-teams/provenance.json +851 -0
  194. gatewaysdk/environment/schema/connectors/microsoft-teams/scope.md +231 -0
  195. gatewaysdk/environment/schema/connectors/microsoft-teams/teams-types.json +1710 -0
  196. gatewaysdk/environment/schema/connectors/microsoft-teams/world.json +858 -0
  197. gatewaysdk/environment/schema/connectors/netsuite/handlers.py +32 -0
  198. gatewaysdk/environment/schema/connectors/netsuite/parity.json +50 -0
  199. gatewaysdk/environment/schema/connectors/netsuite/provenance.json +137 -0
  200. gatewaysdk/environment/schema/connectors/netsuite/scope.toml +78 -0
  201. gatewaysdk/environment/schema/connectors/netsuite/world.json +16243 -0
  202. gatewaysdk/environment/schema/connectors/salesforce/handlers.py +806 -0
  203. gatewaysdk/environment/schema/connectors/salesforce/parity.json +46 -0
  204. gatewaysdk/environment/schema/connectors/salesforce/provenance.json +143 -0
  205. gatewaysdk/environment/schema/connectors/salesforce/scope.toml +174 -0
  206. gatewaysdk/environment/schema/connectors/salesforce/world.json +4695 -0
  207. gatewaysdk/environment/schema/connectors/slack/MODEL.md +236 -0
  208. gatewaysdk/environment/schema/connectors/slack/capabilities.json +1039 -0
  209. gatewaysdk/environment/schema/connectors/slack/handlers.py +762 -0
  210. gatewaysdk/environment/schema/connectors/slack/parity.json +65 -0
  211. gatewaysdk/environment/schema/connectors/slack/provenance.json +294 -0
  212. gatewaysdk/environment/schema/connectors/slack/scope.toml +44 -0
  213. gatewaysdk/environment/schema/connectors/slack/world.json +4993 -0
  214. gatewaysdk/environment/schema/connectors/workday/handlers.py +75 -0
  215. gatewaysdk/environment/schema/connectors/workday/parity.json +36 -0
  216. gatewaysdk/environment/schema/connectors/workday/provenance.json +179 -0
  217. gatewaysdk/environment/schema/connectors/workday/scope.toml +180 -0
  218. gatewaysdk/environment/schema/connectors/workday/world.json +806 -0
  219. gatewaysdk/environment/schema/data.py +593 -0
  220. gatewaysdk/environment/schema/extract.py +263 -0
  221. gatewaysdk/environment/schema/host.py +2437 -0
  222. gatewaysdk/environment/schema/host_surfaces.py +275 -0
  223. gatewaysdk/environment/schema/platform.py +1272 -0
  224. gatewaysdk/environment/schema/scaffold.py +250 -0
  225. gatewaysdk/environment/schema/skill.py +118 -0
  226. gatewaysdk/environment/schema/skills/agents/connector-template-author.md +202 -0
  227. gatewaysdk/environment/schema/skills/connector-schema-authoring/CONNECTORS.md +331 -0
  228. gatewaysdk/environment/schema/skills/connector-schema-authoring/CONVENTIONS.md +100 -0
  229. gatewaysdk/environment/schema/skills/connector-schema-authoring/SKILL.md +313 -0
  230. gatewaysdk/environment/schema/skills/world-data-ingestion/ROWS.md +223 -0
  231. gatewaysdk/environment/schema/skills/world-data-ingestion/SKILL.md +293 -0
  232. gatewaysdk/environment/schema/skills/worlds-getting-started/SKILL.md +390 -0
  233. gatewaysdk/environment/schema/slack.py +757 -0
  234. gatewaysdk/environment/schema/snapshot.py +479 -0
  235. gatewaysdk/environment/schema/store.py +904 -0
  236. gatewaysdk/environment/schema/tasks.py +525 -0
  237. gatewaysdk/environment/schema/tools_world.py +322 -0
  238. gatewaysdk/environment/schema/validation.py +577 -0
  239. gatewaysdk/environment/schema/worker.py +78 -0
  240. gatewaysdk/environment/schema/workers.py +500 -0
  241. gatewaysdk/environment/schema/world_tests.py +336 -0
  242. gatewaysdk/environments/__init__.py +24 -0
  243. gatewaysdk/environments/client.py +486 -0
  244. gatewaysdk/environments/types.py +318 -0
  245. gatewaysdk/execution/__init__.py +15 -0
  246. gatewaysdk/execution/base.py +64 -0
  247. gatewaysdk/execution/client_server.py +443 -0
  248. gatewaysdk/execution/events.py +69 -0
  249. gatewaysdk/execution/inter_process.py +16 -0
  250. gatewaysdk/execution/shared_memory.py +282 -0
  251. gatewaysdk/experiments/__init__.py +90 -0
  252. gatewaysdk/experiments/assignment.py +177 -0
  253. gatewaysdk/experiments/client.py +877 -0
  254. gatewaysdk/experiments/exposure.py +222 -0
  255. gatewaysdk/experiments/types.py +81 -0
  256. gatewaysdk/importers/__init__.py +49 -0
  257. gatewaysdk/importers/_normalize.py +91 -0
  258. gatewaysdk/importers/builder.py +173 -0
  259. gatewaysdk/importers/client.py +95 -0
  260. gatewaysdk/importers/langsmith.py +196 -0
  261. gatewaysdk/importers/recipes.py +249 -0
  262. gatewaysdk/instrumentation/__init__.py +300 -0
  263. gatewaysdk/instrumentation/agentops.py +314 -0
  264. gatewaysdk/instrumentation/agentops_langchain.py +45 -0
  265. gatewaysdk/instrumentation/base.py +119 -0
  266. gatewaysdk/instrumentation/litellm.py +83 -0
  267. gatewaysdk/instrumentation/registry.py +273 -0
  268. gatewaysdk/instrumentation/vllm.py +81 -0
  269. gatewaysdk/instrumentation/weave.py +500 -0
  270. gatewaysdk/integrations/__init__.py +15 -0
  271. gatewaysdk/integrations/gateway/__init__.py +11 -0
  272. gatewaysdk/integrations/gateway/client.py +171 -0
  273. gatewaysdk/integrations/tool_access.py +549 -0
  274. gatewaysdk/litagent/__init__.py +11 -0
  275. gatewaysdk/litagent/decorator.py +536 -0
  276. gatewaysdk/litagent/litagent.py +252 -0
  277. gatewaysdk/llm_proxy.py +1742 -0
  278. gatewaysdk/logging.py +370 -0
  279. gatewaysdk/memory.py +278 -0
  280. gatewaysdk/personas.py +186 -0
  281. gatewaysdk/platform/__init__.py +17 -0
  282. gatewaysdk/platform/builder.py +221 -0
  283. gatewaysdk/platform/compatibility.py +67 -0
  284. gatewaysdk/platform/manifest.py +185 -0
  285. gatewaysdk/platform/orchestrator.py +901 -0
  286. gatewaysdk/platform/registry.py +122 -0
  287. gatewaysdk/platform/worker.py +864 -0
  288. gatewaysdk/replay/__init__.py +1032 -0
  289. gatewaysdk/replay/pytest.py +56 -0
  290. gatewaysdk/reward.py +7 -0
  291. gatewaysdk/run.py +1781 -0
  292. gatewaysdk/runner/__init__.py +11 -0
  293. gatewaysdk/runner/agent.py +878 -0
  294. gatewaysdk/runner/base.py +182 -0
  295. gatewaysdk/runner/legacy.py +309 -0
  296. gatewaysdk/security.py +700 -0
  297. gatewaysdk/semconv.py +170 -0
  298. gatewaysdk/server.py +399 -0
  299. gatewaysdk/sessions.py +282 -0
  300. gatewaysdk/store/__init__.py +45 -0
  301. gatewaysdk/store/base.py +908 -0
  302. gatewaysdk/store/client_server.py +2093 -0
  303. gatewaysdk/store/collection/__init__.py +30 -0
  304. gatewaysdk/store/collection/base.py +587 -0
  305. gatewaysdk/store/collection/memory.py +970 -0
  306. gatewaysdk/store/collection/mongo.py +1412 -0
  307. gatewaysdk/store/collection_based.py +1823 -0
  308. gatewaysdk/store/gateway.py +983 -0
  309. gatewaysdk/store/gateway_listener.py +465 -0
  310. gatewaysdk/store/listener.py +58 -0
  311. gatewaysdk/store/memory.py +396 -0
  312. gatewaysdk/store/mongo.py +165 -0
  313. gatewaysdk/store/redis_stream.py +517 -0
  314. gatewaysdk/store/sqlite.py +3 -0
  315. gatewaysdk/store/threading.py +370 -0
  316. gatewaysdk/store/utils.py +142 -0
  317. gatewaysdk/tracer/__init__.py +14 -0
  318. gatewaysdk/tracer/base.py +286 -0
  319. gatewaysdk/tracer/dummy.py +106 -0
  320. gatewaysdk/tracer/otel.py +559 -0
  321. gatewaysdk/tracing/__init__.py +110 -0
  322. gatewaysdk/tracing/api.py +808 -0
  323. gatewaysdk/tracing/attributes.py +9 -0
  324. gatewaysdk/tracing/context.py +272 -0
  325. gatewaysdk/tracing/exporters/__init__.py +10 -0
  326. gatewaysdk/tracing/exporters/gateway.py +228 -0
  327. gatewaysdk/tracing/identity.py +288 -0
  328. gatewaysdk/tracing/init.py +620 -0
  329. gatewaysdk/tracing/instrumentors/__init__.py +15 -0
  330. gatewaysdk/tracing/instrumentors/claude_agent_sdk.py +766 -0
  331. gatewaysdk/tracing/instrumentors/instrumentation_principles.md +294 -0
  332. gatewaysdk/tracing/instrumentors/registry.py +352 -0
  333. gatewaysdk/tracing/mapping.py +729 -0
  334. gatewaysdk/tracing/processors.py +393 -0
  335. gatewaysdk/tracing/push.py +617 -0
  336. gatewaysdk/tracing/push_models.py +247 -0
  337. gatewaysdk/tracing/semconv.py +294 -0
  338. gatewaysdk/tracing/span_builder.py +356 -0
  339. gatewaysdk/trainer/__init__.py +6 -0
  340. gatewaysdk/trainer/init_utils.py +263 -0
  341. gatewaysdk/trainer/legacy.py +359 -0
  342. gatewaysdk/trainer/registry.py +12 -0
  343. gatewaysdk/trainer/trainer.py +638 -0
  344. gatewaysdk/types/__init__.py +63 -0
  345. gatewaysdk/types/core.py +556 -0
  346. gatewaysdk/types/resources.py +204 -0
  347. gatewaysdk/types/tracer.py +515 -0
  348. gatewaysdk/types/tracing.py +162 -0
  349. gatewaysdk/users.py +251 -0
  350. gatewaysdk/utils/__init__.py +1 -0
  351. gatewaysdk/utils/id.py +18 -0
  352. gatewaysdk/utils/metrics.py +1025 -0
  353. gatewaysdk/utils/otel.py +550 -0
  354. gatewaysdk/utils/otlp.py +556 -0
  355. gatewaysdk/utils/redact.py +22 -0
  356. gatewaysdk/utils/server_launcher.py +1045 -0
  357. gatewaysdk/utils/system_snapshot.py +90 -0
  358. gatewaysdk/verl/__init__.py +8 -0
  359. gatewaysdk/verl/__main__.py +6 -0
  360. gatewaysdk/verl/async_server.py +46 -0
  361. gatewaysdk/verl/config.yaml +27 -0
  362. gatewaysdk/verl/daemon.py +1154 -0
  363. gatewaysdk/verl/dataset.py +44 -0
  364. gatewaysdk/verl/entrypoint.py +248 -0
  365. gatewaysdk/verl/trainer.py +549 -0
  366. gatewaysdk/world_browser.py +748 -0
  367. gatewaysdk/world_data.py +453 -0
  368. gatewaysdk/world_sessions.py +978 -0
  369. gatewaysdk/world_tasks.py +285 -0
  370. gatewaysdk/world_tools.py +115 -0
  371. gatewaysdk/worlds.py +639 -0
  372. gatewaysdk-0.3.2.dist-info/METADATA +236 -0
  373. gatewaysdk-0.3.2.dist-info/RECORD +376 -0
  374. gatewaysdk-0.3.2.dist-info/WHEEL +4 -0
  375. gatewaysdk-0.3.2.dist-info/entry_points.txt +5 -0
  376. gatewaysdk-0.3.2.dist-info/licenses/LICENSE +19 -0
@@ -0,0 +1,331 @@
1
+ # Connector reference
2
+
3
+ Per-connector authoring guidance. Revalidate vendor sources and sandbox availability
4
+ before implementation; target labels below are goals, not measured SDK fidelity.
5
+ The previously referenced `connector-fidelity-scope.md` is absent from this checkout.
6
+ Keep pinned sources with each authored template rather than relying on that missing plan.
7
+
8
+ ## Contents
9
+
10
+ - [Shape, model sources, and surfaces](#shape-model-sources-and-surfaces)
11
+ - [Sandboxes and what they can seed](#sandboxes-and-what-they-can-seed)
12
+ - [Type-mapping notes](#type-mapping-notes)
13
+ - [Status of templates in the SDK](#status-of-templates-in-the-sdk)
14
+ - [Source dossiers and sim strategy](#source-dossiers-and-sim-strategy)
15
+ - [How to use a dossier](#how-to-use-a-dossier)
16
+
17
+ ## Shape, model sources, and surfaces
18
+
19
+ | Connector | Shape | Model source (importer kind) | Tenant channel (describe) | MCP surface today (optional) | Target label |
20
+ | --- | --- | --- | --- | --- | --- |
21
+ | Slack | base | official Slack docs; pinned emulator as secondary inventory (`docs`) | none | [native structured capture and hosted world tools](../../../documentation/integrations/gateway-tool-access.md), no native live MCP catalog | synthetic for fixtures; subset for captured worlds until measured replay |
22
+ | GitHub | base | `github/rest-api-description` OpenAPI (`openapi`); GraphQL introspection | none | Merge connector; GitHub's official MCP server as a remote mirror | mimic |
23
+ | Salesforce | tenant-shaped | standard objects from `sobjects/describe` as a skeleton (`describe`) | same describe per org: **required** at bind | Merge connector; native passthrough for describe and SOQL | mimic per tenant |
24
+ | Google Workspace | mixed | discovery document `admin.googleapis.com/$discovery/rest?version=directory_v1` (`discovery`) | custom user schemas `customer/{id}/schemas` (optional) | Merge brokers Drive and Calendar | mimic |
25
+ | Okta | mixed | `okta-management-openapi-spec` (`openapi`) | user and group schema API `/api/v1/meta/schemas/user/default` (optional) | none yet; native provider if a live surface is wanted | mimic |
26
+ | Microsoft 365 / Entra ID | mixed | Graph `$metadata` OData CSDL (`odata-csdl`) | directory, schema, open extensions (optional) | none yet | mimic directory; subset licensed workloads |
27
+ | Microsoft Teams | base | authored Graph v1.0 collaboration subset (`docs`, CSDL) | none | none | provisional `subset`; synthetic fixtures, live checks skipped |
28
+ | LDAP / Active Directory | mixed | RFC 4512 subschema; AD `cn=Schema,cn=Configuration` (`ldap-subschema`) | same subschema per directory (optional) | none; non-HTTP provider only if a live surface is wanted | mimic |
29
+ | Jamf Pro | mixed | per-instance OpenAPI at `https://<instance>/api/schema`; Classic API (`openapi`) | extension attributes; per-instance spec (optional) | none yet | mimic records; subset live inventory |
30
+ | Kandji (Iru) | base | docs and Postman collection; community OpenAPI 3.1 conversion; vendor OpenAPI unconfirmed (`docs`) | none | none yet | subset |
31
+ | Apple Business Manager | base | Apple DocC JSON, API 2.4 (`docs`); no downloadable OAS | none | none | subset |
32
+ | Workday | tenant-shaped | public WSDL/XSD per service as a skeleton (`wsdl-xsd`) | tenant WSDL: **required** at bind | check the Merge catalog cache (HRIS) | subset until a tenant exists, then mimic |
33
+ | NetSuite | tenant-shaped | REST `metadata-catalog` in OpenAPI 3.0 and JSON Schema per record type (`describe`) | same catalog per account: **required** at bind | check the Merge catalog cache (accounting) | mimic per tenant |
34
+
35
+ ## Sandboxes and what they can seed
36
+
37
+ | Connector | Sandbox we can own | Seedable through the write API | Only from the real world |
38
+ | --- | --- | --- | --- |
39
+ | Slack | free workspace | channels, users (invites), messages, files | nothing |
40
+ | GitHub | free test organization plus the Gateway GitHub App | repos, issues, PRs, reviews, check runs | nothing |
41
+ | Salesforce | Developer Edition org; scratch orgs via Dev Hub | any sObject; SOQL reads | nothing |
42
+ | Google Workspace | dedicated test domain (small paid seats) or trial | users, groups, org units, custom schemas, Drive and Calendar content | Chrome and mobile devices |
43
+ | Okta | free developer / integrator org | users, groups, memberships, apps, assignments | system log (generated by seeding) |
44
+ | Microsoft 365 / Entra ID | Entra ID free tenant always; E5 developer sandbox only for eligible accounts (Visual Studio Pro or Enterprise) | users, groups, service principals, directory extensions | licensed workloads without the E5 sandbox |
45
+ | Microsoft Teams | no sandbox used for this schema milestone | not exercised; fixtures are synthetic and loaded through the SDK store | live response fidelity remains unvalidated |
46
+ | LDAP / Active Directory | Docker OpenLDAP or Samba AD DC | everything | nothing |
47
+ | Jamf Pro | Jamf developer sandbox or trial instance | computers and mobile devices via Classic API, groups, policies, extension attributes | inventory detail from a live agent |
48
+ | Kandji (Iru) | sandbox via the account team (docs mention one) | blueprints, library items, users, tags | devices |
49
+ | Apple Business Manager | our own ABM org with Apple devices; no developer sandbox | writes exist since API 2.0, but land in production, so we do not seed | devices, MDM assignments |
50
+ | Workday | commercial or partner tenant only; no public sandbox | workers, positions, organizations once a tenant exists | nothing in principle |
51
+ | NetSuite | partner developer account (SuiteCloud Developer Network); customer sandboxes are paid add-ons | any record the role permits; SuiteQL reads | nothing |
52
+
53
+ For Jamf, Kandji and ABM, one enrolled test Mac gives the device entities at least one
54
+ real row; captured exports from that tenant become the goldens.
55
+
56
+ ## Type-mapping notes
57
+
58
+ - Temporal values: vendor `date-time` maps to strict RFC 3339 `format: date-time`; exact calendar dates map to `format: date`; vendor date-times that allow a space separator use `vendor-date-time`. Use `time` only when seconds and an explicit timezone are required.
59
+ - Slack message `ts` remains an exact string; Unix seconds use integers and conversation `updated` uses milliseconds. See the [model guide](../../../gatewaysdk/sdk/src/gatewaysdk/environment/schema/connectors/slack/MODEL.md) for workspace identity and normalization.
60
+ - Regex patterns are unsupported in the current payload and tool-contract dialect. Record the lost constraint and any future mapper obligation explicitly; do not add unsupported keywords.
61
+ - Polymorphic lookups (Salesforce `WhoId`, `WhatId`) are nullable strings without a relationship; note them in the scope file.
62
+ - Vendor enums (picklists, Graph enum types, Okta statuses) become `enum`; tenant-added picklist values arrive through the overlay.
63
+ - Composite keys are declared in order (`repo_id`, `number` for GitHub issues; `calendar_id`, `id` for events).
64
+ - Reserved prefixes (`_`, `sqlite_`, `gateway_`, `benchmark_`) and the `payload` property name cannot appear in entity or field names; prefix entities with the connector (`okta_users`, `sf_accounts`).
65
+
66
+ ## Status of templates in the SDK
67
+
68
+ | Slug | State | Notes |
69
+ | --- | --- | --- |
70
+ | slack | package 2.1.1 / domain 2.0.0 / mapping 1 | 34 entities, 27 tools; empty init or populated synthetic/selected capture → immutable hosted world; [on-demand fixtures](../../../samples/schema-worlds/README.md#slack-fixtures) |
71
+ | github | spec-derived, wave 1 | base; pinned GitHub REST OpenAPI plus the GraphQL review-state declaration. 8 entities / 1,662 recursive fields / 4 tools. Vendor nesting is retained, including pull-request and review `_links`; route containment and selected relationship projections remain direct fields where the vendor payload does not carry route context. Issue state/state-reason come from declared REST sibling value blocks; review state comes from `PullRequestReviewState`; merged user `type` stays open because not every read form closes it. `subset` until a test-org round trip and synthetic goldens exist. |
72
+ | salesforce | docs-derived, wave 1 (re-import) | tenant-shaped skeleton from seven pinned Winter '27 Object Reference pages: 7 entities / 656 recursive fields / 4 tools. **Describe-on-bind is required** for the org's actual fields, relationships, picklists, custom schema, and permissions. Compound addresses retain vendor nesting; exact dates use `format: date`; sparse `sf_users.Username` uniqueness is enforced without requiring the field on every SOQL projection. Only explicit vendor value blocks become enums; org-controlled picklists remain open strings. Polymorphic `WhoId`/`WhatId` remain unenforced. `subset`: no Developer Edition/scratch-org round trip or goldens. |
73
+ | google-drive, google-calendar | hand-authored (#219) | mixed; re-import from the discovery documents in wave 2 |
74
+ | linear, jira | hand-authored (#219) | base; not in the eleven, kept as samples |
75
+ | microsoft-teams | authored schema-only base | [Usage, artifacts, scope, and pinned evidence](../../../documentation/features/microsoft-teams-schema.md); no tools or live integration |
76
+ | custom | hand-authored (#219) | the blank starting point for any arbitrary connector |
77
+ | workday | hand-authored, wave 3 | tenant-shaped skeleton from pinned public WWS v46.2 WSDL/XSD files for Human Resources, Staffing, Absence Management, and Compensation: 7 entities / 289 recursive fields / 3 tools. **Describe-on-bind is required** for an actual tenant. Workday-namespaced `wd:enumeration` blocks are used only where the selected reference-ID types declare them; tenant business values remain open. `xsd:date` maps to `format: date`; `xsd:time` remains unformatted because the source permits a missing timezone. Nested references remain vendor-shaped; references ending in typed ID arrays or repeated sections are not falsely narrowed to one foreign key. `subset`: no tenant round trip or goldens. |
78
+ | kandji | hand-authored, wave 3 | base; transcribed from the pinned vendor Postman collection rendered by api-docs.iru.com, with the community OpenAPI used only as a cross-check. 8 entities / 85 recursive fields / 3 tools. Device `user` stays as the vendor's nested object-or-empty-string shape; `/user/id` is enforced when assigned and the empty-string sentinel is treated as absent. Blueprint type and library-item status use vendor-declared value blocks; platform values are example-derived and completeness remains unverified. Apple-family app shape only; Windows/Android forms need a polymorphic-key model. `subset`: no account-team sandbox, tenant round trip, or goldens. |
79
+ | jamf | docs-derived, wave 3 | mixed; authored from pinned Jamf Pro 11.31.0 and Classic API 11.28.0 reference pages because no per-instance `/api/schema` was available. 8 entities / 373 recursive fields / 4 tools. Computer inventory retains optional whole `general`/`hardware`/`operatingSystem`/`userAndLocation` sections; policies and profiles preserve nested scope. `ComputerGeneral.initialEntryDate` retains `format: date`. Nested serial-number uniqueness is technically expressible but is not asserted because the pinned OpenAPI does not declare it. Extension-attribute definitions are base schema; collected values remain tenant data. `subset` until a sandbox round trip and goldens exist. |
80
+ | apple-business-manager | docs-derived, wave 3 | base; authored from 96 pinned Apple Business API 2.4 DocC JSON documents. 18 entities / 159 recursive fields / 2 read tools spanning organization devices, AppleCare, MDM device summaries/details, servers and assignments, activities, users, groups, organizational units, blueprints, configurations, and linkage tables. Vendor `attributes` nesting is preserved; nested `enrolledUserId` and user-group `ouId` relationships are enforced, while `roleOuList[].ouId` remains unenforced because it traverses an array. Enums come only from DocC `possibleValues`/`allowedValues`. No write tools are shipped: Apple has no sandbox and writes affect production. `subset`: no tenant round trip or goldens. |
81
+ | netsuite | docs-derived, wave 3 | tenant-shaped skeleton from the exact archived 2023.2 REST API Browser plus supporting Oracle metadata/error docs: 9 entities / 5,259 recursive fields / 3 tools. **Describe-on-bind is required** for role/account-specific records, custom fields, lists, segments, enums, and nullability. Record references and local sublists/subrecords preserve vendor nesting; customer, vendor, and journal-entry `/subsidiary/id` relationships are enforced. Polymorphic references and collection-item paths remain unenforced. Sixty declared date fields use `format: date`; date-times retain `date-time`. No uniqueness is inferred from business prose when the pinned schema does not declare it. `suiteql` is not shipped because the world store has no query surface. `subset`: no account metadata overlay, round trip, or goldens. |
82
+ | spycloud | brief only, wave 5 | base; public per-operation OpenAPI 3.1 at docs.spycloud.com (45 operations confirmed: 20 Investigations, 18 Enterprise, 3 SIP, 3 IDLink, 1 NIST); `x-api-key`; `{cursor, hits, results}` envelope at 1,000/page. Per-key allow-lists, masking and hashing are world config, not an overlay. Starts at `subset`; TRM's captures raise the agent's selectors to `mimic`. |
83
+ | constella | brief only, wave 5 | base; API reference is MNDA-gated, no OpenAPI/SDK public. 14 selector searches named via the vendor's Maltego transform catalog, 0 method/path pairs. Cannot be mocked faithfully without TRM's transport, envelopes and error bodies. |
84
+ | cloudburst | brief only, wave 5 | base; Cloudburst Technologies (`cloudburst.info`). 2 agent-facing operations confirmed from vendor screenshots plus the signal object shape; `GET /api/schema/?format=json` is a credential-gated OpenAPI document, so one authenticated fetch with TRM's key turns this into a real `openapi` import. Vendor timestamps carry no zone offset. |
85
+ | torchlight | dropped | name is ambiguous (Torchlight AI is a defence geospatial platform with no public API; the functional fit is Searchlight Cyber). Parked until TRM confirms the vendor. |
86
+ | okta, microsoft-entra, ldap | none | created through this checklist in waves 2 and 3 |
87
+
88
+ Slack retains optional join/leave, pins, bookmarks, user groups and presence.
89
+ Scenario grading uses bounded set comparisons; paginated reads assemble selected
90
+ rows with per-call association maps. Capability defaults expand into complete
91
+ published entries and own capture classifications. Exact template/lock pins
92
+ remain required: prior versions retain their bytes and cannot silently refresh
93
+ under the new package. The [scale regressions](../../../gatewaysdk/sdk/tests/environment/test_schema_slack_scale.py)
94
+ exercise synthetic materialization and read/grading behavior, not live replay.
95
+
96
+ ## Source verification
97
+
98
+ SDK template and native Slack guidance revalidated 2026-09-07 while integrating
99
+ `ba89fe16` with `015d6b25`. Inspected
100
+ `gatewaysdk/sdk/src/gatewaysdk/environment/schema/{scaffold.py,slack.py,_slack_fidelity.py,connectors/}`,
101
+ `gatewaysdk/sdk/tests/environment/test_schema_{scaffold,slack_scale}.py`, and
102
+ `gateway/packages/shared/src/server/services/NativeSlackService.ts`.
103
+ Other vendor rows are guidance to revalidate, not newly tested integrations.
104
+
105
+ ## Source dossiers and sim strategy
106
+
107
+ One block per connector: where the truth lives, what we can read from the connector itself,
108
+ which event schemas exist (change events are the cheapest fidelity signal), the error
109
+ format the world must reproduce, the sandbox, and the recommended way to build the
110
+ high-fidelity sim. Verified 2026-09-06; "verify" marks a claim to confirm before relying on it.
111
+ Pin every spec by URL and SHA-256 in `provenance.json`.
112
+
113
+ ### Slack (base)
114
+
115
+ - Docs: https://api.slack.com/methods and https://api.slack.com/docs
116
+ - Machine-readable: `slackapi/slack-api-specs` (archived 2024-03, read-only): Web API as OpenAPI 2.0 `web-api/slack_web_openapi_v2.json`, Events API as AsyncAPI `events-api/`. Treat as a frozen baseline; newer methods come from the docs.
117
+ - Introspection: none. Slack has no per-workspace schema.
118
+ - Events: the AsyncAPI catalog of event payloads (`message`, `member_joined_channel`, `file_shared`).
119
+ - Errors: `{"ok": false, "error": "not_in_channel"}` with a string code per method.
120
+ - Sandbox: a free workspace; seed channels, users, messages, files through the Web API.
121
+ - Sim: import the OpenAPI response objects (`objs_channel`, `objs_user`, `objs_message`, `objs_file`) as entities; keep `ts` as the message key; model `ok`/`error` responses on every tool; goldens from the native provider's captures. Slack's own AsyncAPI event shapes double as ingestion fixtures.
122
+
123
+ ### GitHub (base)
124
+
125
+ - Docs: https://docs.github.com/en/rest and https://docs.github.com/en/graphql
126
+ - Machine-readable: `github/rest-api-description` (`descriptions/api.github.com/api.github.com.json`, OpenAPI 3.0; `descriptions-next` for 3.1), refreshed continuously; GraphQL public schema via `octokit/graphql-schema` or introspection; webhook payload JSON Schemas via `@octokit/webhooks-schemas` (`schema.json`, daily updated) with example payloads in `@octokit/webhooks-examples`.
127
+ - **Enum values are not in the REST description** (corrected 2026-09-06): issue `state` and user `type` are enumerated only on the `webhooks_issue` / `webhooks_user` schemas in the same document, and review `state` only in the GraphQL `PullRequestReviewState`. Take them from those siblings and record which one.
128
+ - Introspection: GraphQL `__schema` on `api.github.com/graphql`. No per-tenant schema.
129
+ - Events: webhook schemas above cover every entity change; use them as the change-event shape and as ingestion fixtures.
130
+ - Errors: `{"message": ..., "errors": [{"resource", "field", "code"}], "documentation_url"}`; 422 for validation.
131
+ - Sandbox: a free test organization plus the Gateway GitHub App.
132
+ - Sim: import component schemas `repository`, `issue`, `pull-request`, `pull-request-review`, `check-run`, `commit`, `simple-user`, `label` from the REST description; composite keys `(repo_id, number)`; error shape from the docs; goldens from the test org through the app. The webhook example payloads seed `data/records.json` without inventing anything.
133
+
134
+ ### Okta (mixed)
135
+
136
+ - Docs: https://developer.okta.com/docs/reference/
137
+ - Machine-readable: `okta/okta-management-openapi-spec` (`dist/spec.json`, also npm `@okta/openapi`); the vendor states it is generated from the Management API.
138
+ - Introspection: User schema `GET /api/v1/meta/schemas/user/default` and app user schemas, group schema; these carry the org's custom attributes and are the overlay source. System Log event types catalog at https://developer.okta.com/docs/reference/api/event-types/.
139
+ - Events: Event Hooks deliver `LogEvent` objects (same shape as the System Log API); event-hook-eligible types are a subset of the catalog.
140
+ - Errors: `{"errorCode": "E0000001", "errorSummary": ..., "errorCauses": [...]}`.
141
+ - Sandbox: free developer / integrator org; seed users, groups, memberships, apps, assignments by API. System Log fills itself.
142
+ - Sim: import `User`, `Group`, `Application`, `AppUser`/assignment, `LogEvent` from the OpenAPI; overlay from the schema API; model `errorCode` responses; goldens from the developer org. The System Log is the natural "events" entity and a strong replay source.
143
+
144
+ ### Google Workspace (mixed)
145
+
146
+ - Docs: https://developers.google.com/workspace/admin/directory/reference/rest, Reports API under the Admin SDK, Drive https://developers.google.com/workspace/drive/api/reference/rest/v3, Calendar v3 reference.
147
+ - Machine-readable: discovery documents, `https://www.googleapis.com/discovery/v1/apis/{api}/{version}/rest` (`admin/directory_v1`, `admin/reports_v1`, `drive/v3`, `calendar/v3`); list all at `https://discovery.googleapis.com/discovery/v1/apis`.
148
+ - Introspection: custom user schemas `GET customer/{customerId}/schemas` (overlay source). Drive and Calendar have no per-tenant schema.
149
+ - Events: Admin SDK Reports API activity events (admin, login, drive, calendar applications) give change records; Drive `changes` and push notifications; Calendar push notifications.
150
+ - Errors: `{"error": {"code": 404, "message": ..., "errors": [{"domain", "reason", "message"}]}}`.
151
+ - Sandbox: a dedicated test domain (small paid seats) or a trial; seed users, groups, org units, custom schemas, Drive and Calendar content.
152
+ - Sim: import `schemas` from each discovery document (`User`, `Group`, `Member`, `OrgUnit`, `Role`, `File`, `Permission`, `Revision`, `Event`, `CalendarListEntry`); overlay from custom schemas; error envelope from the docs; Reports API activity records as the events entity and as replay fixtures.
153
+
154
+ ### Microsoft 365 / Entra ID (mixed)
155
+
156
+ - Docs: https://learn.microsoft.com/en-us/graph/api/overview
157
+ - Machine-readable: Graph `$metadata` (OData CSDL) live at `https://graph.microsoft.com/v1.0/$metadata`; the same, plus a client-optimized OpenAPI 3.0, in `microsoftgraph/msgraph-metadata` (`openapi/v1.0/openapi.yaml`, `clean_v10_metadata/`).
158
+ - Introspection: directory extensions (`extensionProperties` on applications), schema extensions (`/schemaExtensions`), open extensions on objects; tenant-defined attribute sets and custom security attributes. Overlay source.
159
+ - Events: change notifications (`changeNotification` with `resourceData`, `changeType` created/updated/deleted); `directoryAudit` and `signIn` under `/auditLogs`.
160
+ - Errors: `{"error": {"code": "Request_ResourceNotFound", "message": ..., "innerError": {...}}}`.
161
+ - Sandbox: Entra ID free tenant (directory objects); the E5 developer sandbox only for eligible accounts.
162
+ - Sim: import `user`, `group`, `directoryObject` membership, `servicePrincipal`, `application`, `directoryRole`, `signIn`, `directoryAudit` from CSDL; navigation properties become relationships; overlay from extension properties; error envelope from the docs; audit and sign-in logs as the events entities. Scope the CSDL hard; it is hundreds of types.
163
+
164
+ ### LDAP / Active Directory (mixed)
165
+
166
+ - Docs: RFC 4511 (protocol), RFC 4512 (directory information models, subschema), RFC 4519 (standard attribute types); AD schema reference https://learn.microsoft.com/en-us/windows/win32/adschema/active-directory-schema and the [MS-ADTS] schema section.
167
+ - Machine-readable: the subschema subentry read over LDAP (`subschemaSubentry` attribute of the root DSE, then `attributeTypes` and `objectClasses`); AD's schema partition `CN=Schema,CN=Configuration,<forest>` with `classSchema` and `attributeSchema` objects.
168
+ - Introspection: the same read against the target directory is the overlay source (AD schema extensions, custom object classes).
169
+ - Events: none over LDAP; AD exposes changes through `uSNChanged`, DirSync control, or Windows event logs. Model `uSNChanged` and `whenChanged` on entries.
170
+ - Errors: LDAP result codes (`noSuchObject` 32, `constraintViolation` 19, `entryAlreadyExists` 68, `objectClassViolation` 65).
171
+ - Sandbox: Docker OpenLDAP (`inetOrgPerson`, `groupOfNames`, `posixAccount`) and Samba AD DC (`user`, `group`, `computer`, `organizationalUnit`). Fully offline.
172
+ - Sim: import object classes for the scope from the subschema (MUST → required, MAY → optional, syntax OID → type); DN is the key, `objectClass` a required array, membership as `member`/`memberOf` join entities; result codes as the error table. Two templates or one with a directory flavor: OpenLDAP vs AD attribute names differ (`cn`/`uid` vs `sAMAccountName`, `userAccountControl`).
173
+
174
+ ### Jamf Pro (mixed)
175
+
176
+ - Docs: https://developer.jamf.com/jamf-pro/reference/jamf-pro-api and the Classic API reference; `https://developer.jamf.com/jamf-pro/llms.txt` indexes every page and endpoint, and any docs page serves Markdown with `.md` appended.
177
+ - Machine-readable: per-instance OpenAPI 3 at `https://<instance>.jamfcloud.com/api/schema`; Classic API is XML/JSON without a *whole-API* spec. Confirmed 2026-09-05: every `reference/<page>.md` on developer.jamf.com — Classic API pages included — embeds a complete OpenAPI 3.0.1 fragment for that one endpoint, with its `components.schemas` and its documented error responses. That is what the `jamf` template was built from, so an author needs no instance to get real schemas; the pages label themselves Jamf Pro API 11.31.0 and Classic API 11.28.0. Page slugs are not guessable (policies are `findpoliciesbyid`, not `findpolicybyid`) — take them from the section `llms.txt`.
178
+ - Introspection: the per-instance spec plus extension attributes (`/api/v1/computer-extension-attributes`, mobile device equivalents). Overlay source.
179
+ - Events: webhooks with documented payloads per event (`ComputerAdded`, `ComputerInventoryCompleted`, `MobileDeviceEnrolled`, `PushSent`, ...) at https://developer.jamf.com/jamf-pro/docs/webhooks-1.
180
+ - Errors: Jamf Pro API `{"httpStatus": 404, "errors": [{"code", "description", "id", "field"}]}`; Classic API returns HTML/XML status bodies.
181
+ - Sandbox: Jamf developer sandbox or trial instance; computer and mobile device records can be created through the Classic API, inventory detail needs an enrolled device.
182
+ - Sim: import `computer-inventory`, `mobile-device`, `computer-group`, `policy` (Classic), `configuration-profile`, `extension-attribute` from the instance spec; overlay from extension attributes; webhook payloads as change-event fixtures; one enrolled test Mac for real inventory rows.
183
+
184
+ ### Kandji (Iru) (base)
185
+
186
+ - Docs: https://api-docs.kandji.io/, which **301s to https://api-docs.iru.com/** (Kandji is Iru). The page is a Postman documenter shell; the authoritative artifact is the collection JSON it renders, which is directly fetchable and pinnable (verify `_postman_id` matches the shell's `collectionId`). Tenant URL `https://<subdomain>.api.kandji.io`; EU `.api.eu.kandji.io`.
187
+ - Machine-readable: no vendor-published OpenAPI confirmed; a community OpenAPI 3.1 generated from Kandji's Postman collection at `MScottBlake/kandji-openapi` (verify against the docs before importing).
188
+ - Introspection: none.
189
+ - Events: webhooks documented on the API site (verify event list and payloads).
190
+ - Errors: **not** `detail`/`error` objects (corrected 2026-09-06). Bodies are a JSON string or an array of strings, with a response-code table on the docs index.
191
+ - Sandbox: request through the account team; devices cannot be created by API.
192
+ - Sim: `docs` importer with a transcribed scope (`devices`, `device_details`, `blueprints`, `library_items`, `users`, `tags`, `device_apps`); captured exports from our tenant and one enrolled Mac as goldens; label `subset`.
193
+
194
+ ### Apple Business Manager (base)
195
+
196
+ - Docs: https://developer.apple.com/documentation/applebusinessapi and https://developer.apple.com/documentation/apple-school-and-business-manager-api; WWDC25 session 258.
197
+ - **Not read-only** (corrected 2026-09-06, API 2.4): 2.0 added `POST /v1/orgDeviceActivities`, 2.1 added mdmServer create/update/delete. The blocker is that we own no sandbox, so writes would land in our production org, not that the surface is read-only. Apple publishes no downloadable OAS URL; the machine-readable form is Apple's own DocC JSON (`developer.apple.com/tutorials/data/documentation/applebusinessapi.json`), which is pinnable.
198
+ - Machine-readable: Apple states the Business API is specified in an OpenAPI-compliant format; locate the spec download on the API documentation page and pin it (verify the exact URL).
199
+ - Introspection: none.
200
+ - Events: none; batch activity status is polled.
201
+ - Errors: JSON:API-style `{"errors": [{"id", "status", "code", "title", "detail"}]}`. Apple publishes no `code` vocabulary; only per-endpoint HTTP statuses are evidenced, so raise the documented status and reason rather than invent codes.
202
+ - Sandbox: none; our own ABM org with real devices; read-only API.
203
+ - Sim: import `OrgDevice`, `MdmServer`, device assignment and `OrgDeviceActivity` from the spec; seed from exports of our org; label `subset`.
204
+
205
+ ### Workday (tenant-shaped)
206
+
207
+ - Docs: https://community.workday.com/sites/default/files/file-hosting/productionapi/ (WWS directory with WSDL and XSD per service and version; `Human_Resources`, `Staffing`, `Financial_Management`); REST at developer.workday.com behind Community login; RaaS custom reports.
208
+ - Machine-readable: public WSDL/XSD per service and version (e.g. `.../productionapi/Human_Resources/v19/Human_Resources.wsdl`, newer versions under `versions/`).
209
+ - Introspection: the tenant's WSDL at `https://<host>.workday.com/ccx/service/<tenant>/Human_Resources/v44?wsdl` carries the tenant's custom objects and fields; RaaS report definitions describe custom reports. Overlay source, required.
210
+ - Events: no public change feed; integrations use "Get_*" with effective dating and transaction log queries.
211
+ - Errors: SOAP faults with Workday validation messages.
212
+ - Sandbox: customer or partner tenant only.
213
+ - Sim: `wsdl-xsd` importer over the public WSDL for the skeleton (`Worker`, `Position`, `Job_Profile`, `Organization`, `Location`, `Compensation`), effective-dated fields modelled as `effective_date` on rows; overlay from the tenant WSDL when one exists; label `subset` until then.
214
+
215
+ ### Salesforce (tenant-shaped)
216
+
217
+ - Docs: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/ (REST), SOQL reference, Metadata and Tooling APIs.
218
+ - Machine-readable: per-org, generated: global describe `GET /services/data/vXX.X/sobjects/`, `GET .../sobjects/{name}/describe` (fields, types, picklist values, `referenceTo`, `nillable`, `createable`, `updateable`); OpenAPI 3 generation for the sObjects REST API (`/services/data/vXX.X/async/specifications/oas3`, beta) which reflects the org's custom objects and fields.
219
+ - Introspection: the same describe; it is the model, not an overlay. The shared template is a skeleton of standard objects.
220
+ - Events: Change Data Capture and Platform Events (event message with `ChangeEventHeader`: `changeType`, `changedFields`, `recordIds`); the Pub/Sub API delivers them.
221
+ - Errors: array of `{"message", "errorCode", "fields"}` with codes such as `REQUIRED_FIELD_MISSING`, `FIELD_CUSTOM_VALIDATION_EXCEPTION`, `INVALID_FIELD`, `NOT_FOUND`.
222
+ - Sandbox: Developer Edition org, scratch orgs via Dev Hub; any sObject seedable; SOQL for reads.
223
+ - Sim: `describe` importer against a Developer Edition org for the skeleton, then against the bound org for the tenant model; picklists to enums, `referenceTo` to relationships, polymorphic lookups as nullable ids; the error array as the error table; CDC messages as change-event fixtures; SOQL subset as the query tool, scoped by the golden set.
224
+
225
+ ### NetSuite (tenant-shaped)
226
+
227
+ - Docs: https://docs.oracle.com/en/cloud/saas/netsuite/ns-online-help/ (REST web services, SuiteQL, Records Catalog).
228
+ - Machine-readable: per-account `GET /services/rest/record/v1/metadata-catalog` (OpenAPI 3.0 with `Accept: application/swagger+json`, JSON Schema with `application/schema+json`), including custom records and fields; the Records Catalog UI documents record types.
229
+ - Introspection: the same catalog; it is the model.
230
+ - Events: no public change feed; SuiteScript user events and REST `lastModifiedDate` filters.
231
+ - Errors: `{"type", "title", "status", "o:errorDetails": [{"detail", "o:errorCode"}]}`.
232
+ - Sandbox: partner developer account through the SuiteCloud Developer Network; customer sandboxes are paid add-ons.
233
+ - Sim: `describe` importer over the metadata catalog for `customer`, `vendor`, `inventoryItem`, `salesOrder`, `invoice`, `journalEntry`, `account`, `subsidiary`; sublists as child entities; SuiteQL subset as the query tool; error object from the docs.
234
+
235
+ ### Linear (base)
236
+
237
+ - Docs: https://linear.app/developers/graphql and https://linear.app/developers/webhooks
238
+ - Machine-readable: GraphQL introspection on `https://api.linear.app/graphql` (public schema also browsable on Apollo Studio); the TypeScript SDK is generated from it.
239
+ - Introspection: none per workspace beyond workflow states and labels, which are data, not schema.
240
+ - Events: webhooks for Issue, Comment, Project, ProjectUpdate, Cycle, Label, User, IssueLabel, Document, Reaction, SLA; payload mirrors the GraphQL entity.
241
+ - Errors: GraphQL `errors[]` with `extensions.type` and `userPresentableMessage`.
242
+ - Sandbox: a free workspace; everything seedable through the API.
243
+ - Sim: `graphql` importer (add to the importer list) over introspection for `Team`, `User`, `Project`, `Cycle`, `Issue`, `Comment`, `WorkflowState`, `IssueLabel`; webhook payloads as change-event fixtures.
244
+
245
+ ### Jira Cloud (mixed)
246
+
247
+ - Docs: https://developer.atlassian.com/cloud/jira/platform/rest/v3/
248
+ - Machine-readable: OpenAPI at `https://developer.atlassian.com/cloud/jira/platform/swagger-v3.v3.json`.
249
+ - Introspection: `GET /rest/api/3/field` (global custom fields), `GET /rest/api/3/issue/createmeta?expand=projects.issuetypes.fields` (per project and issue type, including team-managed fields), issue types, statuses, workflows. Overlay source.
250
+ - Events: webhooks (`jira:issue_created`, `jira:issue_updated` with `changelog`, comment and worklog events).
251
+ - Errors: `{"errorMessages": [...], "errors": {"field": "message"}}`.
252
+ - Sandbox: a free Jira Cloud site.
253
+ - Sim: import `IssueBean`, `Project`, `User`, `Comment`, `Transition`, `Sprint` (Agile API) from the OpenAPI; custom fields via overlay from `field` and `createmeta`; webhook `changelog` as the change-event fixture.
254
+
255
+ ### Google Drive and Google Calendar (base)
256
+
257
+ - Covered under Google Workspace above: discovery documents `drive/v3` and `calendar/v3`, push notifications and `changes` for Drive, Reports API activity for both, the Google error envelope, and the test domain sandbox.
258
+ - Sim: import `File`, `Permission`, `Revision`, `Comment`, `Drive`; `Event`, `CalendarListEntry`, `Acl` from discovery; `attendees` stays nested on events.
259
+
260
+ ### Notion (base)
261
+
262
+ - Docs: https://developers.notion.com/reference
263
+ - Machine-readable: `makenotion/notion-mcp-server/scripts/notion-openapi.json` (OpenAPI 3.1, used by Notion's own MCP server).
264
+ - Introspection: `GET /v1/databases/{id}` returns the database's property schema; treat Notion databases as tenant-defined entities layered over fixed `Page`, `Block`, `Database`, `User`, `Comment`.
265
+ - Events: Notion webhooks for page, database, and comment events (verify current event list).
266
+ - Errors: `{"object": "error", "status", "code": "validation_error", "message"}`.
267
+ - Sandbox: a free workspace with an internal integration.
268
+ - Sim: import the fixed objects from the OpenAPI; a per-database overlay produced from the database schema endpoint; the existing `notion-sim` tasks migrate onto it.
269
+
270
+ ### Zoom (base)
271
+
272
+ - Docs: https://developers.zoom.us/docs/api/
273
+ - Machine-readable: `zoom/api` repository `openapi.v2.json` (OpenAPI 2); the marketplace also serves per-product OAS files (Meetings, Users, Phone).
274
+ - Introspection: none.
275
+ - Events: webhooks and the Webhook event catalog (`meeting.started`, `meeting.participant_joined`, `recording.completed`).
276
+ - Errors: `{"code": 3001, "message": ...}`.
277
+ - Sandbox: a free developer account with a Server-to-Server OAuth app; meetings and users seedable.
278
+ - Sim: import `User`, `Meeting`, `Participant` (reports), `Recording` from the OAS; webhook events as change-event fixtures.
279
+
280
+ ### Stripe (base)
281
+
282
+ - Docs: https://docs.stripe.com/api
283
+ - Machine-readable: `stripe/openapi` (`openapi/spec3.json`, public; `spec3.sdk.json` with internal annotations), versioned with the API.
284
+ - Introspection: none.
285
+ - Events: `Event` objects with `data.object` for every resource change; the OpenAPI enumerates event types.
286
+ - Errors: `{"error": {"type": "invalid_request_error", "code", "param", "message"}}`.
287
+ - Sandbox: Stripe test mode plus `stripe/stripe-mock`, a mock server generated from the same OpenAPI that validates request parameters and 404s unknown paths.
288
+ - Sim: import `customer`, `payment_intent`, `charge`, `invoice`, `subscription`, `event` from `spec3.json`; the error object from the spec; `stripe-mock` is the reference for what a spec-generated mock can and cannot do (it validates shapes, holds no state), which is exactly the gap a schema world fills.
289
+
290
+ ### Existing sims (synthetic)
291
+
292
+ - E-commerce bench, EnterpriseOps HR, ATS sim, Zapier pipeline sim, Google Drive sim, Notion sim: the model source is their committed `seeds/schema.sql` or `db/schema.sql`. Write `world.json` from the DDL (a `ddl` importer once it exists), keep tasks and verifiers, regenerate artifacts, label `synthetic` unless a vendor spec replaces the hand-written model.
293
+
294
+ ### Cloudburst (base)
295
+
296
+ - Docs: https://burst.cloud/api/ is the only public description (prose plus five response screenshots, 2023 assets still served in 2026); the real developer docs are a password-gated ReadMe site titled "Cloudburst API" at https://docs.cloudburst.info/. The vendor is Cloudburst Technologies, Inc. (burst.cloud), off-chain crypto/financial-crime intelligence from Telegram, Discord, forums, breaches and stealer logs; not `cloudburst.io` (unregistered), not `cloudbursttech.com` (an unrelated Berlin data-recovery firm), not CloudburstMC or hydro-project. No SDK on PyPI, npm or GitHub; no MCP registry listing although the homepage sells an MCP server.
297
+ - Machine-readable: an OpenAPI 3 document exists but needs a credential: `GET https://cloudburst.info/api/schema/` answers `401` with `Content-Type: application/vnd.oai.openapi` (`?format=json` → `+json`), i.e. drf-spectacular on a Django REST Framework service whose root is `https://cloudburst.info/api/v1/` (confirmed 2026-09-08). Until TRM's key fetches it, the model comes from the screenshots (`GET {{api_url}}/users?phone=…`, `GET {{api_url}}/users?first_name=…`, a signal object with nested `channel{entity_id, participants, score{crowd, time}}` and `message{post_id, message_text, post_datetime}`) and from the 2024 marketing bundle (`web.archive.org/web/2024id_/https://burst.cloud/assets/main.a014b33b.js`), which embeds 1,000 vendor-published signal rows `{id, signal_type: buy|sell, signal_datetime, commodity, base_commodity, exchanges[]}`. The screenshots' `{{api_url}}` is a Postman variable: ask for the collection too.
298
+ - Introspection: none per customer; the schema is vendor-defined (base). The vendor's own OpenAPI endpoint is the introspection, credential-gated.
299
+ - Events: none public. "Streaming is on the roadmap" (api page, unchanged since 2023); the Chainalysis OSINT-tab integration (2024-06) advertises "real-time alerts" without a payload; the MCP server's tool list is unpublished. Treat signals as the change-record entity for now.
300
+ - Errors: DRF envelope. Confirmed live: `401 {"detail": "Authentication credentials were not provided."}` (`code: not_authenticated`). DRF defaults to keep until captured: `404 {"detail": "Not found."}`, `403 {"detail": "You do not have permission to perform this action."}`, `400 {"<field>": ["…"]}` / `non_field_errors`, `429 {"detail": "Request was throttled. Expected available in N seconds."}` with `Retry-After`. Rate limits and the auth header scheme (DRF `Token` vs Bearer) are unverified.
301
+ - Sandbox: none; demo by request only (`contact@burst.cloud`), docs password-gated. Live checks are `skipped` unless TRM lends a developer key. No public TRM–Cloudburst integration exists (TRM's published OSINT sources are Google, Chainabuse and Flashpoint, March 2026); which surface TRM's agent uses (REST, MCP, bulk) is knowable only from its logs.
302
+ - Sim: hand-author from `--connector custom`: `cloudburst_channels` (key `entity_id`, Telegram peer id string), `cloudburst_users` (key `id`, `entity_id` unique, nested `phones[]`), `cloudburst_channel_memberships` (`user_id, channel_entity_id`; `flair`, `joined_at`; the vendor inlines these as `users[].channels[]`), `cloudburst_messages` (`channel_entity_id, post_id`; global uniqueness of `post_id` unverified), `cloudburst_signals` (key `id`; `price_data{expected_gain, stop_loss, entry_price_range, target_prices}`, `exchanges[]`); `cloudburst_wallets` and `cloudburst_entities` only as labelled skeletons because no public source shows a field. Vendor timestamps carry no zone (`2023-05-01T01:40:21`): use `vendor-date-time`. Read tools return bare arrays as captured; the DRF error table on every tool; synthetic fixtures shaped from the 1,000 bundle rows; goldens from TRM's sanitized captures; label provisional `subset`. Re-derive as an `openapi` import the day `/api/schema/?format=json` is pinned.
303
+
304
+ ### Constella Intelligence (base)
305
+
306
+ - Docs: https://constella.ai/data/developer-portal/ and https://constella.ai/data/intelligence-api/. **The API reference is behind an MNDA** ("We offer API documentation to partners and prospective partners who have executed an MNDA with us"); tokens are issued to licensed or evaluating partners via `support@constellaintelligence.com`. Vendor formed 2020-12 from 4iQ + Alto Analytics; products are Hunter (investigator UI at `app.constellaintelligence.com`), Hunter+ DRP (formerly Dome), and the Intelligence API. Legacy site `constellaintelligence.com`.
307
+ - Machine-readable: **none public** (verified 2026-09-08): no OpenAPI, Postman, or SDK repository despite the claim of Python/JavaScript/Go libraries. The best public interface description is the vendor-hosted Maltego transform catalog at https://docs.maltego.com/en/support/solutions/articles/15000053397-constella-intelligence — 14 `search_for_*` selectors (email, username, phone_number, domain, ip, company, brand, ssn, credit_card, tax_id, nid, passport, driver_license, facebook_id) and 18 `extract_*` record attributes (address, company, credit_card, dob, domain, email, name, password, phone_number, source, ssn, username, ip v4/v6, facebook_information, tax_id, national_id, passport, driver_license); auth settings `constella_app_token`, `constella_token`, `constella_username`. Vocabulary for password state (Plaintext / Hashed / No Passwords) and hash algorithms (MD5, MySQL323, SHA-1, Bcrypt, private) from the 2026 Identity Breach Report (`https://constella.ai/wp-content/uploads/2026_Feb_IdentityBreachReport.pdf`, SHA-256 `26ea4e2c…950ec`); operation families (Search API, Monitoring API with bulk registration and callback-URL alerts, Password API per NIST 800-63b) from the 2019 4iQ IDTheft datasheet (`https://ppbw.pl/wp-content/uploads/2019/11/i-LEAD-Industry-Days-4iQ-2.pdf`, SHA-256 `bf71498b…966a`) — historical, verify against TRM's logs.
308
+ - Introspection: none. One fixed lake for every customer ("over 50 record attributes", "over 200 normalized fields"); tenant differences are entitlements (licensed selectors, clear-text vs hashed/masked returns) and monitored populations, which are rows, not schema.
309
+ - Events: no public change feed for the lake. Monitoring alerts to a callback URL (4iQ 2019, verify current form); Dome/Hunter+ findings reach Splunk through `TA-constella-dome-app-for-splunk` v1.0.9 (https://splunkbase.splunk.com/app/6299), whose field mapping lives only in the package. Freshness claim "60-day" for infostealer data.
310
+ - Errors: **not public.** No envelope, code vocabulary, or rate-limit header is documented; pricing is "per-query or per-monitored-identity". Model statuses only (400/403 unlicensed selector, 401 bad token, 429 quota, empty list for no hits) and mark each `unverified` until TRM supplies observed bodies.
311
+ - Sandbox: "Sandbox Environment: Test your implementation with demo data" exists only under the MNDA + evaluation agreement; nothing self-serve. Live checks `skipped` unless TRM lends a dev key.
312
+ - Sim: hand-author from `--connector custom`: `constella_sources` (breach/exposure event; type enum breach|infostealer_log|combolist|paste|forum_registration|marketplace|surface_web; `exposure_date`), `constella_records` (one row per breach record, every Maltego-extractable attribute nullable, `password_state` + `hash_algorithm` enums, `source_id`), `constella_identities` (entity-resolved, `risk_score`), optional `constella_infostealer_logs` + `constella_cookies` (active|expired) and `constella_monitors` + `constella_alerts` per TRM's usage. Index records by every selector column so `search_records{selector_type, value}` returns believable multi-source hits; wholly synthetic fixtures (passwords and government IDs are sensitive by construction); label provisional `subset` with transport, error envelope, and live checks listed as the reasons. The three things only TRM can supply: base URL + method/path + auth header per call; raw hit/miss envelopes per selector with pagination and field names; observed error bodies and limits.
313
+
314
+ ### SpyCloud (base)
315
+
316
+ - Docs: https://docs.spycloud.com/public-sc (index at https://docs.spycloud.com/public-sc/llms.txt; append `.md` to any page); API guidelines https://docs.spycloud.com/public-sc/docs/api-guidelines; public "Limited Data Schema" https://docs.spycloud.com/public-sc/docs/data-schema (the full 200+ asset schema is at `portal.spycloud.com/docs/sc-full-data-schema`, login required); severity scale in https://docs.spycloud.com/public-sc/docs/faqs.
317
+ - Machine-readable: every reference page under https://docs.spycloud.com/public-sc/reference/ embeds a per-operation OpenAPI 3.1 document (`investigations-api` 1.1 at `https://api.spycloud.io/investigations-v2`, `enterprise-ato-prevention-api` 1.1 at `https://api.spycloud.io/enterprise-v2`, `session-identity-protection-api` at `sip-v1`, `idlink-api` at `idl-v2`); `api-evangelist/spycloud` `openapi/_original/*.yml` bundles the same exports per product (third-party profile). Response schemas are mostly `{}`; entity fields come from `data-schema.md` plus integration fixtures: `demisto/content` `Packs/SpyCloudEnterpriseProtection` (client source, raw `test_data/*.json` envelopes, README context examples), `elastic/integrations` `packages/spycloud` (CEL request programs, `fields.yml`, `sample_event.json`), `eatm-cert-user/spycloud` (watchlist identifier pull).
318
+ - **Tier decides the selector set, not the schema**: Investigations exposes 19 `/breach/data/<selector>/{value}` lookups (email, domain, username, ip, password, phone, email-username, social-handle, log-id, infected-machine-id, cc/bank/drivers-license/national-id/passport/SSN as hashes) with `fuzzy` on username/password/handle/email-username; Enterprise exposes 5 of them plus `/breach/data/watchlist`, `/watchlist/*` identifier CRUD (the only writes), and `/compass/*`. Both share `/breach/catalog` and `/breach/catalog/{id}`, the header `x-api-key`, and the envelope `{"cursor", "hits", "results"}` at a fixed 1,000 per page with a ~2-minute cursor lifetime.
319
+ - Introspection: none; no per-tenant schema. Per-key configuration instead: function allow-list, asset allow-list (masked assets return exactly `********`; `document_id`, `source_id`, `spycloud_publish_date` always shown), optional asset hashing with a `salt` query param, IP allow-list, monthly quota. Model as world config, never as an overlay.
320
+ - Events: none (no webhooks). Change signal is `spycloud_publish_date` and `record_modification_date` with `since`/`until`/`since_modification_date`/`until_modification_date`; the Elastic CEL programs are the reference polling loop over `/breach/catalog`, `/breach/data/watchlist`, `/compass/data`.
321
+ - Errors: JSON on every code; 400 invalid identifier/param, 403 bad key / non-allow-listed IP / function not allowed (header `SpyCloud-Error: Invalid API key|Invalid IP`), 429 rate limit (header `x-amzn-ErrorType: TooManyRequestsException`, "Too many requests") and 429 quota (`LimitExceededException`, "Limit exceeded"; rate limit takes precedence), 500, 504 (Enterprise), 422 (IDLink >2000 matches). Bodies carry `message` or `errorMessage`; exact 4xx bodies are unpublished — verify with a key.
322
+ - Sandbox: none public and no trial; keys are per licence via `portal.spycloud.com`, IP allow-listed, quota'd. Live checks `skipped` unless TRM lends a dev key; synthetic fixtures from the public examples, goldens from TRM's sanitized captures.
323
+ - Sim: import the readme.io OpenAPI (per page or the `_original` bundle) for paths and params; author `spycloud_breaches` (`id` int, `uuid`) and `spycloud_breach_records` (`document_id`, `source_id → id`, `severity` 2|5|20|25|26) from `data-schema.md`, adding the fields only evidenced by Elastic/XSOAR fixtures (`ip_addresses`, `sighting`, `record_*_date`, `breach_title`, `breach_category`, PII, `premium_flag`) with per-field provenance; carry catalog `type` uppercase as observed (`PUBLIC`/`PRIVATE`) and note the docs' lowercase; implement each selector as an indexed filter over records (email lowercased; hash selectors; `type` filter semantics unverified); derive catalog `assets` counts from records; reproduce the envelope, 1,000-row cursor pages with expiry, masking and both 429 headers as config; `spycloud_watchlist_identifiers` (`identifier`, `watchlist_type` email|domain|subdomain|ip, `verified`, `last_discovered`) only for the Enterprise configuration. Label provisional `subset` until TRM supplies the full schema page and captures.
324
+
325
+ ## How to use a dossier
326
+
327
+ 1. Start from the machine-readable source; only fall back to docs where none exists.
328
+ 2. Read the connector itself for the overlay wherever an introspection row exists; for tenant-shaped connectors that read is the model.
329
+ 3. Use the event or webhook schema as the shape of change records and as ingestion fixtures; they are the cheapest real-world evidence.
330
+ 4. Model the error format; a world that never says `REQUIRED_FIELD_MISSING` teaches the wrong reflexes.
331
+ 5. Seed the sandbox, pull, ingest, replay; goldens are synthetic-ized before they are committed.
@@ -0,0 +1,100 @@
1
+ # Generation conventions
2
+
3
+ Every connector template, whether hand-authored, imported, or uploaded, follows these
4
+ conventions so worlds look and behave the same across connectors. `test_schema_scaffold.py::test_committed_templates_follow_the_generation_conventions`
5
+ enforces the mechanical ones on every committed template; the rest are review items.
6
+
7
+ ## Contents
8
+
9
+ - [Identity](#identity)
10
+ - [Entities](#entities)
11
+ - [Fields and types](#fields-and-types)
12
+ - [Tools](#tools)
13
+ - [Data, verifiers, and provenance](#data-verifiers-and-provenance)
14
+ - [Layout](#layout)
15
+ - [Patterns borrowed from prior art (Arga Labs twins)](#patterns-borrowed-from-prior-art-arga-labs-twins)
16
+
17
+ ## Identity
18
+
19
+ | Thing | Convention | Example |
20
+ | --- | --- | --- |
21
+ | Template slug | lowercase, hyphenated, the vendor's common name | `google-calendar`, `microsoft-entra`, `apple-business-manager` |
22
+ | Domain `$id` | `urn:gateway:connector:<slug>` | `urn:gateway:connector:okta` |
23
+ | Package id | `gateway-connector-<slug>` in the template; `init --name` overrides for a world | `gateway-connector-okta` |
24
+ | `domain_version`, package `version` | semver strings, start at `1.0.0`; bump `domain_version` on any entity change, package `version` on tool or handler change | |
25
+ | Manifest | `[environment] connector = "<slug>"` records the template a world came from | |
26
+ | Shape | recorded in `provenance.json` as `shape: base \| tenant-shaped \| mixed` | |
27
+
28
+ ## Entities
29
+
30
+ - **One prefix per template**, short and stable, applied to every entity: `slack_`, `github_`, `sf_`, `okta_`, `gws_`, `entra_`, `ldap_`, `jamf_`, `kandji_`, `abm_`, `workday_`, `netsuite_`, `drive_`, `calendar_`, `linear_`, `jira_`, `notion_`, `zoom_`, `stripe_`. The `custom` template uses `records`. The reservation lives in `test_schema_scaffold.py::PREFIXES`; claim a prefix there before authoring. Prefix collisions are refused; two templates never share a prefix.
31
+ - Entity names are plural snake_case nouns after the prefix: `okta_users`, `github_pull_requests`. No abbreviations beyond the prefix.
32
+ - Every entity declares `primary_key`; use the vendor's id (`id`, `Id`, `key`, `account_id`) rather than inventing one. Composite keys follow the vendor's containment order (`repo_id`, `number`; `calendar_id`, `id`).
33
+ - Relationships point at the parent's primary key and are declared on the child; `on_delete` is always `restrict` (the language allows nothing else).
34
+ - Membership and other many-to-many facts are their own entity with a composite key (`slack_memberships`), never arrays of ids on either side.
35
+ - Uniqueness beyond the key is declared where the vendor enforces it (`slack_channels.name`, `okta_users.login`), not where it merely tends to hold.
36
+
37
+ ## Fields and types
38
+
39
+ - Field names follow the vendor's casing (`Id`, `StageName` for Salesforce; `created_at` for GitHub). Do not normalize casing; fidelity beats uniformity.
40
+ - Reuse `schema/base.json` primitives: `Id`, `Label`, `Text`, `Email`, `Timestamp`. `base.json` is byte-identical across templates; add a primitive to the shared file, never to one template.
41
+ - Nullable versus optional are distinct: a field the vendor always returns but may be null is `type: [..., "null"]` and required; a field the vendor may omit is optional. Never both unless the vendor does both.
42
+ - Timestamps are `Timestamp` (`format: date-time`). Vendor dates without time are 10-character strings until the compiler has a `date` format; note it in `provenance.json`.
43
+ - Enums are the vendor's literal values, in the vendor's order, including their casing (`"Closed Won"`, `needsAction`). Tenant-added values arrive through the overlay.
44
+ - Numbers carry the vendor's bounds where documented (`probability` 0..1, sizes `minimum: 0`).
45
+ - Polymorphic references (Salesforce `WhoId`) are nullable strings without a relationship, listed under `polymorphic` in `scope.toml`.
46
+ - Free-text bodies use `Text`; names and titles use `Label`; identifiers use `Id`.
47
+
48
+ ## Tools
49
+
50
+ - Tools are optional. When a template ships them, the default set per primary entity is `list_<entities>`, `get_<entity>`, and one write (`create_<entity>` or the vendor's verb such as `post_message`, `transition_issue`, `update_stage`).
51
+ - Names are `verb_noun` in snake_case, vendor verbs preferred where the vendor has a well-known one.
52
+ - Input schemas are closed objects; reads take the parent key (`channel_id`, `repo_id`), writes take a whole entity payload under a singular key (`message`, `issue`, `opportunity`).
53
+ - Every write goes through `gateway_env.store`; handlers raise the vendor's error string for the violations the vendor reports (`not_in_channel`, `invalid_transition`).
54
+ - A template that declares an MCP surface keeps that surface's tool names verbatim and reports parity; it does not rename to fit this convention.
55
+
56
+ ## Data, verifiers, and provenance
57
+
58
+ - `data/records.json` is synthetic and small (a handful of rows per entity, enough to exercise every relationship). `data/initial.json` is produced from it by the fixture mapper with `coverage: partial`. Never vendor or customer data.
59
+ - One starter verifier, `verifiers/state_present.sql`, scoring 1.0 when the first entity holds a row; real tasks replace it.
60
+ - `schema/provenance.json`: `shape`, `source` (`kind`, `url`, `version`, `sha256`), `importer` (name, version) or `authored_by`, `scope_hash`, `generated_at`. Imported templates must round-trip: re-running the importer reproduces `world.json`.
61
+ - `scope.toml` (imported templates): entity allowlist, key overrides, relationship hints, `polymorphic`, and the reason for every exclusion.
62
+ - Goldens under `tests/golden/<slug>/*.jsonl`, synthetic-ized; never raw captures.
63
+
64
+ ## Layout
65
+
66
+ ```
67
+ <slug>/ in gatewaysdk/environment/schema/connectors/
68
+ world.json authored authority (or importer output)
69
+ handlers.py only if the template ships tools
70
+ provenance.json source, shape, importer, hashes
71
+ scope.toml imported templates only
72
+ connector.toml only if the template mirrors a vendor API; init copies it to the world root
73
+ ```
74
+
75
+ A world initialized from a template (`gateway worlds schema init`) adds `gateway-env.toml`,
76
+ `schema/base.json`, `data/`, `verifiers/`, and the generated artifacts, exactly as
77
+ [world-schema.md](../../../documentation/features/world-schema.md) lists them.
78
+
79
+ ## Patterns borrowed from prior art (Arga Labs twins)
80
+
81
+ Arga Labs (argalabs.com; docs.argalabs.com) ships "stateful replicas" of thirty-plus
82
+ services with API, MCP, CLI and UI surfaces over one state store. Their public docs
83
+ describe patterns worth adopting as conventions here; none require new infrastructure.
84
+
85
+ | Arga pattern | Our equivalent or adoption |
86
+ | --- | --- |
87
+ | Twins are **behavioural**: same error responses, rate limits, side effects as the real service ("attempting payment to a non-existent customer returns identical error codes") | The error table per template and vendor-shaped errors raised by handlers; never a generic exception where the vendor has a code |
88
+ | **Stub honesty**: partial endpoints return `_twin_stub: true` and `_twin_warning`; GitHub exposes `GET /admin/stub-hits` | A tool the template does not fully model raises `not_modelled` with the vendor operation name instead of fabricating a response; `fidelity.json` counts them; never fake data for an unmodelled operation |
89
+ | **Deterministic seeding** with reproducible ids per scenario; "empty state unless seeded or created through the API" | `data/initial.json` batches with stable ids; worlds start empty by default; `store.ingest` for seeding code |
90
+ | **Scenarios** as saved `seed_config` per twin, resettable ("reseed from the Scenario") | `BenchmarkContainerCondition` states and `World.reset()`; a scenario is a condition plus its initial batch |
91
+ | **Permission enforcement**: OAuth scopes checked per call (`missing_scope`), capability levels (Notion), tier quotas (`insufficient_space`) | Model scopes and tiers as `benchmark_runtime_parameters` conditions the handlers consult; error codes in the error table; a future compiler feature could declare required scopes per tool |
92
+ | **Webhooks with signed delivery and replay** | Event entities (System Log, audit logs, `stripe_events`) and event fixtures; live webhook emission is out of scope for a mock-tools world today |
93
+ | **State inspection and reset endpoints** (`/admin/state`, `/admin/reset`, `/admin/clock`) | `World.state()`, `store.list()`, `World.reset()`; a clock control (`benchmark_runtime_parameters.now`) is a cheap addition for time-dependent fidelity |
94
+ | **Multiple surfaces over one store** (REST, GraphQL, CLI, MCP, UI share state) | The schema is the store; tools, MCP-mapped tools, custom tools, and a future API-kind twin all sit on it |
95
+ | **Production-seeded scenarios** from connected services | `store.ingest` from a bound connection with PII policy (infra plan B3/B4) |
96
+
97
+ What we deliberately do differently: Arga's twins are code they operate; ours are a
98
+ declarative contract anyone can author or import, measured for fidelity against the
99
+ vendor's own schema, and the same contract serves ingestion, grading, and tools. Their
100
+ per-twin "known limitations" pages are the model for our `fidelity.json` and badge.