@synap-core/cli 1.10.0 → 1.12.2

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 (461) hide show
  1. package/README.md +23 -198
  2. package/dist/build-info.json +6 -0
  3. package/dist/commands/agent-run.js +3 -2
  4. package/dist/commands/agent-run.js.map +1 -1
  5. package/dist/commands/agents.d.ts +33 -17
  6. package/dist/commands/agents.js +203 -237
  7. package/dist/commands/agents.js.map +1 -1
  8. package/dist/commands/app.d.ts +143 -0
  9. package/dist/commands/app.js +523 -0
  10. package/dist/commands/app.js.map +1 -0
  11. package/dist/commands/automate.d.ts +21 -0
  12. package/dist/commands/automate.js +42 -0
  13. package/dist/commands/automate.js.map +1 -0
  14. package/dist/commands/automation-schema.test.d.ts +16 -0
  15. package/dist/commands/automation-schema.test.js +77 -0
  16. package/dist/commands/automation-schema.test.js.map +1 -0
  17. package/dist/commands/automation.d.ts +12 -0
  18. package/dist/commands/automation.js +80 -35
  19. package/dist/commands/automation.js.map +1 -1
  20. package/dist/commands/bridge-setup.d.ts +14 -1
  21. package/dist/commands/bridge-setup.js +392 -128
  22. package/dist/commands/bridge-setup.js.map +1 -1
  23. package/dist/commands/cap-connections.d.ts +4 -4
  24. package/dist/commands/cap-connections.js +14 -14
  25. package/dist/commands/cap-connections.js.map +1 -1
  26. package/dist/commands/capability.d.ts +2 -0
  27. package/dist/commands/capability.js +297 -176
  28. package/dist/commands/capability.js.map +1 -1
  29. package/dist/commands/catalog.d.ts +275 -0
  30. package/dist/commands/catalog.js +481 -0
  31. package/dist/commands/catalog.js.map +1 -0
  32. package/dist/commands/cell.d.ts +155 -8
  33. package/dist/commands/cell.js +416 -40
  34. package/dist/commands/cell.js.map +1 -1
  35. package/dist/commands/centrality.js +3 -14
  36. package/dist/commands/centrality.js.map +1 -1
  37. package/dist/commands/connect.d.ts +38 -13
  38. package/dist/commands/connect.js +68 -167
  39. package/dist/commands/connect.js.map +1 -1
  40. package/dist/commands/connections.d.ts +3 -2
  41. package/dist/commands/connections.js +95 -25
  42. package/dist/commands/connections.js.map +1 -1
  43. package/dist/commands/context.js +9 -2
  44. package/dist/commands/context.js.map +1 -1
  45. package/dist/commands/data-extra.d.ts +34 -0
  46. package/dist/commands/data-extra.js +198 -25
  47. package/dist/commands/data-extra.js.map +1 -1
  48. package/dist/commands/data.d.ts +120 -2
  49. package/dist/commands/data.js +307 -24
  50. package/dist/commands/data.js.map +1 -1
  51. package/dist/commands/diagnose.d.ts +66 -4
  52. package/dist/commands/diagnose.js +329 -29
  53. package/dist/commands/diagnose.js.map +1 -1
  54. package/dist/commands/digest.js +2 -1
  55. package/dist/commands/digest.js.map +1 -1
  56. package/dist/commands/doc.d.ts +25 -4
  57. package/dist/commands/doc.js +100 -18
  58. package/dist/commands/doc.js.map +1 -1
  59. package/dist/commands/doctor.d.ts +130 -0
  60. package/dist/commands/doctor.js +814 -0
  61. package/dist/commands/doctor.js.map +1 -0
  62. package/dist/commands/events.js +3 -1
  63. package/dist/commands/events.js.map +1 -1
  64. package/dist/commands/explain.js +5 -5
  65. package/dist/commands/explain.js.map +1 -1
  66. package/dist/commands/graph.js +5 -3
  67. package/dist/commands/graph.js.map +1 -1
  68. package/dist/commands/import.d.ts +368 -13
  69. package/dist/commands/import.js +1096 -55
  70. package/dist/commands/import.js.map +1 -1
  71. package/dist/commands/init.d.ts +20 -9
  72. package/dist/commands/init.js +433 -973
  73. package/dist/commands/init.js.map +1 -1
  74. package/dist/commands/keys.d.ts +1 -0
  75. package/dist/commands/keys.js +15 -2
  76. package/dist/commands/keys.js.map +1 -1
  77. package/dist/commands/knowledge.d.ts +28 -6
  78. package/dist/commands/knowledge.js +358 -73
  79. package/dist/commands/knowledge.js.map +1 -1
  80. package/dist/commands/launch.js +2 -2
  81. package/dist/commands/launch.js.map +1 -1
  82. package/dist/commands/lens.d.ts +37 -1
  83. package/dist/commands/lens.js +193 -72
  84. package/dist/commands/lens.js.map +1 -1
  85. package/dist/commands/market-authoring.d.ts +72 -0
  86. package/dist/commands/market-authoring.js +566 -0
  87. package/dist/commands/market-authoring.js.map +1 -0
  88. package/dist/commands/market-official.d.ts +58 -0
  89. package/dist/commands/market-official.js +84 -0
  90. package/dist/commands/market-official.js.map +1 -0
  91. package/dist/commands/market.d.ts +419 -20
  92. package/dist/commands/market.js +2124 -193
  93. package/dist/commands/market.js.map +1 -1
  94. package/dist/commands/mcp.d.ts +70 -13
  95. package/dist/commands/mcp.js +308 -40
  96. package/dist/commands/mcp.js.map +1 -1
  97. package/dist/commands/open.d.ts +39 -9
  98. package/dist/commands/open.js +80 -25
  99. package/dist/commands/open.js.map +1 -1
  100. package/dist/commands/playbook.d.ts +42 -0
  101. package/dist/commands/playbook.js +162 -0
  102. package/dist/commands/playbook.js.map +1 -0
  103. package/dist/commands/pod.js +1 -1
  104. package/dist/commands/pod.js.map +1 -1
  105. package/dist/commands/pods.d.ts +19 -0
  106. package/dist/commands/pods.js +220 -85
  107. package/dist/commands/pods.js.map +1 -1
  108. package/dist/commands/proposals-actions.d.ts +62 -0
  109. package/dist/commands/proposals-actions.js +146 -8
  110. package/dist/commands/proposals-actions.js.map +1 -1
  111. package/dist/commands/proposals-await.d.ts +68 -0
  112. package/dist/commands/proposals-await.js +248 -0
  113. package/dist/commands/proposals-await.js.map +1 -0
  114. package/dist/commands/proton-setup.d.ts +73 -0
  115. package/dist/commands/proton-setup.js +577 -0
  116. package/dist/commands/proton-setup.js.map +1 -0
  117. package/dist/commands/providers.d.ts +23 -0
  118. package/dist/commands/providers.js +126 -1
  119. package/dist/commands/providers.js.map +1 -1
  120. package/dist/commands/raycast.js +6 -2
  121. package/dist/commands/raycast.js.map +1 -1
  122. package/dist/commands/rule.d.ts +150 -0
  123. package/dist/commands/rule.js +447 -0
  124. package/dist/commands/rule.js.map +1 -0
  125. package/dist/commands/session-wait.d.ts +111 -0
  126. package/dist/commands/session-wait.js +209 -0
  127. package/dist/commands/session-wait.js.map +1 -0
  128. package/dist/commands/sessions.d.ts +52 -0
  129. package/dist/commands/sessions.js +479 -58
  130. package/dist/commands/sessions.js.map +1 -1
  131. package/dist/commands/skill-manage.d.ts +21 -0
  132. package/dist/commands/skill-manage.js +136 -19
  133. package/dist/commands/skill-manage.js.map +1 -1
  134. package/dist/commands/skills.js +19 -1
  135. package/dist/commands/skills.js.map +1 -1
  136. package/dist/commands/status.d.ts +1 -4
  137. package/dist/commands/status.js +5 -34
  138. package/dist/commands/status.js.map +1 -1
  139. package/dist/commands/statusline.backoff.test.d.ts +13 -0
  140. package/dist/commands/statusline.backoff.test.js +100 -0
  141. package/dist/commands/statusline.backoff.test.js.map +1 -0
  142. package/dist/commands/statusline.js +16 -9
  143. package/dist/commands/statusline.js.map +1 -1
  144. package/dist/commands/sync-status.d.ts +12 -0
  145. package/dist/commands/sync-status.js +125 -0
  146. package/dist/commands/sync-status.js.map +1 -0
  147. package/dist/commands/templates-retire.d.ts +34 -0
  148. package/dist/commands/templates-retire.js +192 -0
  149. package/dist/commands/templates-retire.js.map +1 -0
  150. package/dist/commands/tools.js +6 -21
  151. package/dist/commands/tools.js.map +1 -1
  152. package/dist/commands/tracks.d.ts +51 -0
  153. package/dist/commands/tracks.js +291 -0
  154. package/dist/commands/tracks.js.map +1 -0
  155. package/dist/commands/update.d.ts +3 -11
  156. package/dist/commands/update.js +5 -134
  157. package/dist/commands/update.js.map +1 -1
  158. package/dist/commands/upload.d.ts +68 -0
  159. package/dist/commands/upload.js +257 -0
  160. package/dist/commands/upload.js.map +1 -0
  161. package/dist/commands/vendor.d.ts +28 -0
  162. package/dist/commands/vendor.js +110 -0
  163. package/dist/commands/vendor.js.map +1 -0
  164. package/dist/commands/versions.js +6 -0
  165. package/dist/commands/versions.js.map +1 -1
  166. package/dist/commands/view.js +10 -5
  167. package/dist/commands/view.js.map +1 -1
  168. package/dist/commands/whoami.d.ts +23 -3
  169. package/dist/commands/whoami.js +169 -23
  170. package/dist/commands/whoami.js.map +1 -1
  171. package/dist/commands/worker.d.ts +122 -0
  172. package/dist/commands/worker.js +435 -0
  173. package/dist/commands/worker.js.map +1 -0
  174. package/dist/commands/worker.test.d.ts +1 -0
  175. package/dist/commands/worker.test.js +116 -0
  176. package/dist/commands/worker.test.js.map +1 -0
  177. package/dist/commands/workspace-ops.d.ts +35 -0
  178. package/dist/commands/workspace-ops.js +153 -0
  179. package/dist/commands/workspace-ops.js.map +1 -0
  180. package/dist/index.d.ts +6 -6
  181. package/dist/index.js +1009 -171
  182. package/dist/index.js.map +1 -1
  183. package/dist/lib/agent-connections.d.ts +31 -0
  184. package/dist/lib/agent-connections.js +33 -0
  185. package/dist/lib/agent-connections.js.map +1 -0
  186. package/dist/lib/agent-detect.d.ts +27 -0
  187. package/dist/lib/agent-detect.js +71 -0
  188. package/dist/lib/agent-detect.js.map +1 -0
  189. package/dist/lib/agent-door.d.ts +138 -0
  190. package/dist/lib/agent-door.js +426 -0
  191. package/dist/lib/agent-door.js.map +1 -0
  192. package/dist/lib/agents-config.d.ts +2 -0
  193. package/dist/lib/agents-config.js +4 -9
  194. package/dist/lib/agents-config.js.map +1 -1
  195. package/dist/lib/approval-poll.d.ts +31 -2
  196. package/dist/lib/approval-poll.js +20 -7
  197. package/dist/lib/approval-poll.js.map +1 -1
  198. package/dist/lib/atomic-file.d.ts +48 -0
  199. package/dist/lib/atomic-file.js +129 -0
  200. package/dist/lib/atomic-file.js.map +1 -0
  201. package/dist/lib/auth.d.ts +14 -9
  202. package/dist/lib/auth.js +44 -61
  203. package/dist/lib/auth.js.map +1 -1
  204. package/dist/lib/batch-approval.d.ts +85 -0
  205. package/dist/lib/batch-approval.js +170 -0
  206. package/dist/lib/batch-approval.js.map +1 -0
  207. package/dist/lib/capture-lane.d.ts +6 -5
  208. package/dist/lib/capture-lane.js +11 -8
  209. package/dist/lib/capture-lane.js.map +1 -1
  210. package/dist/lib/capture-structure.d.ts +342 -0
  211. package/dist/lib/capture-structure.js +295 -0
  212. package/dist/lib/capture-structure.js.map +1 -0
  213. package/dist/lib/catalog-templates.d.ts +59 -0
  214. package/dist/lib/catalog-templates.js +126 -0
  215. package/dist/lib/catalog-templates.js.map +1 -0
  216. package/dist/lib/cli-build.d.ts +19 -0
  217. package/dist/lib/cli-build.js +37 -0
  218. package/dist/lib/cli-build.js.map +1 -0
  219. package/dist/lib/conversation-headers.d.ts +18 -0
  220. package/dist/lib/conversation-headers.js +32 -0
  221. package/dist/lib/conversation-headers.js.map +1 -0
  222. package/dist/lib/cp-packages.d.ts +216 -4
  223. package/dist/lib/cp-packages.js +414 -11
  224. package/dist/lib/cp-packages.js.map +1 -1
  225. package/dist/lib/credential-class.d.ts +117 -0
  226. package/dist/lib/credential-class.js +116 -0
  227. package/dist/lib/credential-class.js.map +1 -0
  228. package/dist/lib/describe-lens.d.ts +35 -0
  229. package/dist/lib/describe-lens.js +40 -0
  230. package/dist/lib/describe-lens.js.map +1 -1
  231. package/dist/lib/device-connect.d.ts +125 -0
  232. package/dist/lib/device-connect.js +256 -0
  233. package/dist/lib/device-connect.js.map +1 -0
  234. package/dist/lib/directory-lens.d.ts +99 -0
  235. package/dist/lib/directory-lens.js +187 -0
  236. package/dist/lib/directory-lens.js.map +1 -0
  237. package/dist/lib/exporter-coverage.d.ts +71 -0
  238. package/dist/lib/exporter-coverage.js +97 -0
  239. package/dist/lib/exporter-coverage.js.map +1 -0
  240. package/dist/lib/hub-client.d.ts +43 -9
  241. package/dist/lib/hub-client.js +429 -65
  242. package/dist/lib/hub-client.js.map +1 -1
  243. package/dist/lib/id.d.ts +23 -0
  244. package/dist/lib/id.js +35 -0
  245. package/dist/lib/id.js.map +1 -0
  246. package/dist/lib/init-connect.d.ts +41 -0
  247. package/dist/lib/init-connect.js +75 -0
  248. package/dist/lib/init-connect.js.map +1 -0
  249. package/dist/lib/init-exit.d.ts +24 -0
  250. package/dist/lib/init-exit.js +41 -0
  251. package/dist/lib/init-exit.js.map +1 -0
  252. package/dist/lib/init-flow.d.ts +25 -0
  253. package/dist/lib/init-flow.js +40 -0
  254. package/dist/lib/init-flow.js.map +1 -0
  255. package/dist/lib/init-handoff.d.ts +16 -0
  256. package/dist/lib/init-handoff.js +19 -0
  257. package/dist/lib/init-handoff.js.map +1 -0
  258. package/dist/lib/init-output.d.ts +18 -0
  259. package/dist/lib/init-output.js +43 -0
  260. package/dist/lib/init-output.js.map +1 -0
  261. package/dist/lib/init-pod.d.ts +45 -0
  262. package/dist/lib/init-pod.js +36 -0
  263. package/dist/lib/init-pod.js.map +1 -0
  264. package/dist/lib/installed.d.ts +210 -11
  265. package/dist/lib/installed.js +234 -36
  266. package/dist/lib/installed.js.map +1 -1
  267. package/dist/lib/key-approval.d.ts +57 -0
  268. package/dist/lib/key-approval.js +117 -0
  269. package/dist/lib/key-approval.js.map +1 -0
  270. package/dist/lib/key-diagnosis.d.ts +56 -0
  271. package/dist/lib/key-diagnosis.js +227 -0
  272. package/dist/lib/key-diagnosis.js.map +1 -0
  273. package/dist/lib/key-doctor.d.ts +136 -0
  274. package/dist/lib/key-doctor.js +286 -0
  275. package/dist/lib/key-doctor.js.map +1 -0
  276. package/dist/lib/key-locations.d.ts +120 -0
  277. package/dist/lib/key-locations.js +326 -0
  278. package/dist/lib/key-locations.js.map +1 -0
  279. package/dist/lib/key-source.d.ts +66 -0
  280. package/dist/lib/key-source.js +106 -0
  281. package/dist/lib/key-source.js.map +1 -0
  282. package/dist/lib/key-state.d.ts +70 -0
  283. package/dist/lib/key-state.js +115 -0
  284. package/dist/lib/key-state.js.map +1 -0
  285. package/dist/lib/kind-package.d.ts +181 -0
  286. package/dist/lib/kind-package.js +679 -0
  287. package/dist/lib/kind-package.js.map +1 -0
  288. package/dist/lib/knowledge-title.d.ts +24 -0
  289. package/dist/lib/knowledge-title.js +46 -0
  290. package/dist/lib/knowledge-title.js.map +1 -0
  291. package/dist/lib/knowledge-title.test.d.ts +1 -0
  292. package/dist/lib/knowledge-title.test.js +34 -0
  293. package/dist/lib/knowledge-title.test.js.map +1 -0
  294. package/dist/lib/machine-instance.d.ts +64 -0
  295. package/dist/lib/machine-instance.js +142 -0
  296. package/dist/lib/machine-instance.js.map +1 -0
  297. package/dist/lib/mcp-bridge.d.ts +42 -0
  298. package/dist/lib/mcp-bridge.js +147 -0
  299. package/dist/lib/mcp-bridge.js.map +1 -0
  300. package/dist/lib/mcp-bridge.test.d.ts +1 -0
  301. package/dist/lib/mcp-bridge.test.js +90 -0
  302. package/dist/lib/mcp-bridge.test.js.map +1 -0
  303. package/dist/lib/mcp-call.d.ts +30 -0
  304. package/dist/lib/mcp-call.js +107 -0
  305. package/dist/lib/mcp-call.js.map +1 -0
  306. package/dist/lib/mcp-snippets.d.ts +53 -0
  307. package/dist/lib/mcp-snippets.js +82 -0
  308. package/dist/lib/mcp-snippets.js.map +1 -0
  309. package/dist/lib/next-steps.d.ts +8 -0
  310. package/dist/lib/next-steps.js +31 -1
  311. package/dist/lib/next-steps.js.map +1 -1
  312. package/dist/lib/package-wire.d.ts +179 -0
  313. package/dist/lib/package-wire.js +68 -0
  314. package/dist/lib/package-wire.js.map +1 -0
  315. package/dist/lib/pair-link.d.ts +38 -0
  316. package/dist/lib/pair-link.js +68 -0
  317. package/dist/lib/pair-link.js.map +1 -0
  318. package/dist/lib/pod-wide.d.ts +40 -0
  319. package/dist/lib/pod-wide.js +46 -0
  320. package/dist/lib/pod-wide.js.map +1 -0
  321. package/dist/lib/pod.d.ts +119 -115
  322. package/dist/lib/pod.js +206 -412
  323. package/dist/lib/pod.js.map +1 -1
  324. package/dist/lib/project-ref.d.ts +9 -3
  325. package/dist/lib/project-ref.js +10 -4
  326. package/dist/lib/project-ref.js.map +1 -1
  327. package/dist/lib/review-credential.d.ts +119 -0
  328. package/dist/lib/review-credential.js +147 -0
  329. package/dist/lib/review-credential.js.map +1 -0
  330. package/dist/lib/safe-open.d.ts +49 -0
  331. package/dist/lib/safe-open.js +119 -0
  332. package/dist/lib/safe-open.js.map +1 -0
  333. package/dist/lib/session-lens.d.ts +40 -1
  334. package/dist/lib/session-lens.js +54 -4
  335. package/dist/lib/session-lens.js.map +1 -1
  336. package/dist/lib/superwhisper-import.d.ts +8 -0
  337. package/dist/lib/superwhisper-import.js +14 -7
  338. package/dist/lib/superwhisper-import.js.map +1 -1
  339. package/dist/lib/superwhisper-title.test.d.ts +1 -0
  340. package/dist/lib/superwhisper-title.test.js +18 -0
  341. package/dist/lib/superwhisper-title.test.js.map +1 -0
  342. package/dist/lib/targets.d.ts +134 -10
  343. package/dist/lib/targets.js +962 -258
  344. package/dist/lib/targets.js.map +1 -1
  345. package/dist/lib/template-file.d.ts +78 -0
  346. package/dist/lib/template-file.js +140 -0
  347. package/dist/lib/template-file.js.map +1 -0
  348. package/dist/lib/template-lifecycle.d.ts +217 -0
  349. package/dist/lib/template-lifecycle.js +433 -0
  350. package/dist/lib/template-lifecycle.js.map +1 -0
  351. package/dist/lib/template-steps.d.ts +88 -0
  352. package/dist/lib/template-steps.js +118 -0
  353. package/dist/lib/template-steps.js.map +1 -0
  354. package/dist/lib/time-ago.d.ts +2 -0
  355. package/dist/lib/time-ago.js +15 -0
  356. package/dist/lib/time-ago.js.map +1 -0
  357. package/dist/utils/logger.js +5 -2
  358. package/dist/utils/logger.js.map +1 -1
  359. package/package.json +25 -18
  360. package/skills/README.md +12 -10
  361. package/skills/agent-os/SKILL.md +220 -99
  362. package/skills/manifest.json +2 -2
  363. package/skills/onboard/SKILL.md +61 -25
  364. package/skills/synap/README.md +5 -8
  365. package/skills/synap/SKILL.md +1185 -301
  366. package/skills/synap/_order.txt +7 -0
  367. package/skills/synap/_skill.yaml +1 -1
  368. package/skills/synap/automations.md +15 -0
  369. package/skills/synap/capture.md +54 -151
  370. package/skills/synap/cli-operations.md +24 -18
  371. package/skills/synap/common-mistakes.md +1 -0
  372. package/skills/synap/concepts.md +28 -0
  373. package/skills/synap/content-os.md +92 -0
  374. package/skills/synap/creative-loop.md +15 -10
  375. package/skills/synap/crm.md +21 -52
  376. package/skills/synap/digesting-a-channel.md +25 -0
  377. package/skills/synap/document-embeds.md +141 -47
  378. package/skills/synap/escalation-ladder.md +20 -10
  379. package/skills/synap/focus-sessions.md +47 -21
  380. package/skills/synap/from-intent.md +142 -0
  381. package/skills/synap/governance-rules.md +4 -4
  382. package/skills/synap/governance.md +10 -7
  383. package/skills/synap/hand-off.md +33 -0
  384. package/skills/synap/inline-patterns.md +15 -7
  385. package/skills/synap/lenses.md +33 -15
  386. package/skills/synap/linking.md +41 -40
  387. package/skills/synap/mcp-remote-servers.md +64 -0
  388. package/skills/synap/mental-model.md +24 -22
  389. package/skills/synap/multi-entity-capture.md +6 -4
  390. package/skills/synap/operating-mode-rules.md +1 -1
  391. package/skills/synap/processes.md +118 -0
  392. package/skills/synap/quick-reference.md +5 -1
  393. package/skills/synap/reading.md +3 -1
  394. package/skills/synap/reflexes.md +12 -42
  395. package/skills/synap/viewframe-cells.md +38 -5
  396. package/skills/synap/work-flow.md +1 -1
  397. package/skills/synap/work-model.md +96 -0
  398. package/skills/synap/worked-examples.md +21 -1
  399. package/skills/synap/workspace-design.md +14 -10
  400. package/skills/synap/writes.md +165 -35
  401. package/skills/synap/writing-titles.md +63 -0
  402. package/skills/synap-app/SKILL.md +319 -0
  403. package/skills/synap-app/_order.txt +5 -0
  404. package/skills/synap-app/_skill.yaml +20 -0
  405. package/skills/synap-app/creating-the-base-app.md +64 -0
  406. package/skills/synap-app/governance.md +42 -0
  407. package/skills/synap-app/install-commands.md +55 -0
  408. package/skills/synap-app/overview.md +50 -0
  409. package/skills/synap-app/using-the-sdk.md +73 -0
  410. package/skills/synap-design/SKILL.md +474 -0
  411. package/skills/synap-design/_order.txt +4 -0
  412. package/skills/synap-design/_skill.yaml +21 -0
  413. package/skills/synap-design/loop.md +134 -0
  414. package/skills/synap-design/overview.md +44 -0
  415. package/skills/synap-design/principles.md +130 -0
  416. package/skills/synap-design/system.md +133 -0
  417. package/skills/synap-market/SKILL.md +625 -0
  418. package/skills/synap-market/_order.txt +5 -0
  419. package/skills/synap-market/_skill.yaml +24 -0
  420. package/skills/synap-market/author-and-publish.md +212 -0
  421. package/skills/synap-market/discover-and-fetch.md +59 -0
  422. package/skills/synap-market/governance-and-catalog.md +63 -0
  423. package/skills/synap-market/install.md +133 -0
  424. package/skills/synap-market/overview.md +119 -0
  425. package/skills/synap-schema/SKILL.md +172 -10
  426. package/skills/synap-schema/_order.txt +2 -0
  427. package/skills/synap-schema/_skill.yaml +4 -2
  428. package/skills/synap-schema/common-mistakes.md +4 -2
  429. package/skills/synap-schema/discover-profiles.md +1 -1
  430. package/skills/synap-schema/entity-scope.md +15 -3
  431. package/skills/synap-schema/extend-first.md +29 -0
  432. package/skills/synap-schema/extend-vs-create.md +1 -1
  433. package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
  434. package/skills/synap-schema/property-types.md +1 -1
  435. package/skills/synap-schema/relations.md +1 -1
  436. package/skills/synap-ui/SKILL.md +19 -12
  437. package/skills/synap-ui/_skill.yaml +1 -1
  438. package/skills/synap-ui/ai-companion.md +1 -1
  439. package/skills/synap-ui/arranging-bento.md +2 -0
  440. package/skills/synap-ui/bento-layouts.md +10 -10
  441. package/skills/synap-ui/bento-recipes.md +313 -543
  442. package/skills/synap-ui/four-builds.md +5 -0
  443. package/skills/synap-ui/view-types.md +2 -2
  444. package/skills/synap-ui/widget-catalog.md +22 -278
  445. package/templates/automations/bookmark-enrichment.automation.json +290 -13
  446. package/templates/automations/url-bookmark-capture.automation.json +73 -11
  447. package/templates/skills/authoring-playbooks/SKILL.md +6 -3
  448. package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
  449. package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
  450. package/dist/commands/infra.d.ts +0 -21
  451. package/dist/commands/infra.js +0 -262
  452. package/dist/commands/infra.js.map +0 -1
  453. package/dist/lib/browser-auth.d.ts +0 -35
  454. package/dist/lib/browser-auth.js +0 -170
  455. package/dist/lib/browser-auth.js.map +0 -1
  456. package/dist/lib/openclaw.d.ts +0 -32
  457. package/dist/lib/openclaw.js +0 -164
  458. package/dist/lib/openclaw.js.map +0 -1
  459. package/dist/lib/seed.d.ts +0 -13
  460. package/dist/lib/seed.js +0 -135
  461. package/dist/lib/seed.js.map +0 -1
@@ -0,0 +1,142 @@
1
+ ## From intent — conductor for a new area of work
2
+
3
+ Use this when the user states an **intent** to start or track something that may need structure (a project, domains, kinds, roles, deals-shaped things) — not when they only want to capture a fact into types that already exist (`synap` skill).
4
+
5
+ This skill does **not** provision Company OS. That is `system/agent-os/skill` (install **domains** from templates). This skill decides **what the graph should be**, asks until that is clear, then loads the specialist skill for each write.
6
+
7
+ Load: `system/synap/from-intent`.
8
+
9
+ ### 0. Orient first (firewall)
10
+
11
+ Before proposing structure:
12
+
13
+ 1. `synap_orient` — pending review first; projects; workspaces.
14
+ 2. `synap_list_profiles` — kinds **and** roles (`profileKind`, `applicableKinds`, `parentProfileId`, `entityScope`).
15
+ 3. `synap_ask` — does this intent already live as a project or a cluster of entities?
16
+
17
+ If a close project exists, **reuse it**. Do not mint a twin. Name-match is enough: if orient already lists a project whose description is this company or this commitment, that **is** the project. Ask "reuse «Launch The Architech»?" — do not invent «Architech Business Model» next to it: a business-model method on that project is a **track** on it (`synap_list_tracks` / `synap_start_track`), not a twin project.
18
+
19
+ **Pending review first.** If `startHere.pendingReview.count > 0`, offer to walk the queue before any new structure. Unreviewed work looks missing and gets duplicated.
20
+
21
+ 4. `synap_start_session` — **name the unit of work before you build it.** Title + goal, nothing else; the session is the room the rest of this happens in, not a form to fill. Every write you make afterwards is attributed to it automatically, so the user can open ONE object and see the whole arc instead of loose proposals with no shared story. Reuse an open session that already covers this intent (`synap_list_sessions`) rather than starting a second one. If the intent is a single fact with no structure behind it, skip the session and use the `synap` skill instead — this whole conductor is the wrong door for that.
22
+
23
+ **Propose its `criteria` — do not grade yourself without them.** Two to five binary, observable statements the person can validate or rewrite ("`list_profiles` returns the `grp-run` kind"), not "the pack is good". They may equally be written by the person; what is not allowed is neither. A session with no criteria leaves you nothing to report against but your own opinion, which is how "85% complete" gets said about work nobody can check. Criteria are declarable at `synap_start_session` (as `outcomes` with `kind: 'fact'`, or the older `criteria`) and upserted later with `synap_update_session` — a session created inside a plan carries `expectedOutputs`, not criteria, so set them on the session once it exists.
24
+
25
+ **A discovered prerequisite is a blocking child, not a paragraph in the same session.** When the goal cannot be finished until infrastructure exists, start that infrastructure as its own session: `parentSessionId` of the goal session, plus `suspendedIntent` — one line naming what the goal was about to do. That pair links the child (`spawned_from`) and blocks the parent (`blocked_by` the child). Work the child. Do not keep building the parent goal beside it. The parent stays open and waits; when the child is validated and closed, the parent unblocks and `suspendedIntent` is what you resume. A child that is only a slice of the same goal passes `parentSessionId` alone and does not block the parent.
26
+
27
+ ### 1. Ask before you build (required)
28
+
29
+ Do not install templates, define kinds, or create a project until you can answer these. Ask only what is still unknown — one short pass, not a wizard. Never a 7-step implementation plan in the first reply. What each word means (project, track, step, template, pack, role): `concepts`.
30
+
31
+ | Question | You are distinguishing |
32
+ | ------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------- |
33
+ | What is the **commitment** (the thing we are driving toward over weeks)? | **Project** (optional; gravity). Not a folder. |
34
+ | Which **lasting goals** will it pursue (grow the newsletter, win ten clients…)? | **Tracks** — `synap_start_track`, no template; methods are playbooks sessions follow. |
35
+ | Which **new kinds of things** must be recorded that no workspace owns yet? | **Workspaces** (domains). Four-test + template-first. Missing domain → load `agent-os`. |
36
+ | What is the **thing** vs a **hat** vs a **relationship-with-a-life** vs a **stage**? | Kind vs **facet on any kind** vs deal-pattern kind vs status/view. |
37
+ | What already exists that we can **extend**? | `extend-first` — never a twin slug. |
38
+
39
+ **One space per domain:** A space is a domain, installed once (Content, Brand, CRM…). A project is a filter across spaces. To make something “for project X”: file it into X inside the domain's space (`file_into_project`), and link X to the space (`project_use_workspace`). Never create a space named after a project, a brand or a client.
40
+
41
+ Hats are **not** limited to people and companies. A role is a hat on **whatever kind** `applicableKinds` lists (`item`, `task`, `deal`, …). “This item is an X” is a facet, not a new kind, until X has its own independent life.
42
+
43
+ ### 2. Propose a MINIMAL graph — one question — ONE next write
44
+
45
+ After orient, your first user-facing message is:
46
+
47
+ 1. **Reuse or not** — name the existing project(s) that already match. If none, say you would create one (human / capture-plan / ≥5 evidence). Stop if they must choose.
48
+ 2. **What already covers the intent** — existing workspaces (do not onboard an **empty** domain unless this session's goal needs data there _now_). Existing kinds/roles (extend-first).
49
+ 3. **Exactly one next write** you want confirmed. Examples of ONE: reuse+pin project lens; install one overlay template; widen one role; **or one connected PLAN** (below). Not: project + template + onboard Finance + declare all edges + playbook filed as five separate proposals.
50
+
51
+ Then **wait**. After that write lands (`proposed` is success), the _next_ turn may offer the next one move.
52
+
53
+ #### ONE write may be a whole connected PLAN
54
+
55
+ `synap_capture` accepts `projects[]` / `sessions[]` / `documents[]` / `links[]` / `entities[]` / `relations[]` — and `skills[]` / `automations[]` / `rules[]` — in a **single call** that files **ONE proposal**. Steps reference each other by `ref`; ids exist only after approval. A plan carrying a session or project applies **all-or-none**, compensated if any step fails.
56
+
57
+ This is the difference between a reviewer seeing one graph and deciding once, and seeing fourteen cards with no visible relationship. **Prefer the plan whenever the structure is connected.** It is not a 7-step sequence — it is one decision about one shape.
58
+
59
+ **The trigger is countable, so count.** The moment you are about to make a second `create_*` call for objects that reference each other — a kind and the playbook that uses it, a project and its sessions, a skill and the automation that calls it — stop: that is ONE plan, not N proposals. This is the check that was missing when an agent filed fourteen.
60
+
61
+ **Name what the work will produce.** Each `sessions[]` step takes `expectedOutputs` — the documents, entities and decisions this session owes. List them at plan time: the plan's own object list IS the expected outputs, so "done" is derivable from slots the person can see rather than announced as a percentage. Every slot filled means the work is finished **pending the person's review** — never silently closed.
62
+
63
+ It also resolves ordering that separate proposals cannot: an `automations[]` step whose flow names a skill created by a `skills[]` step in the SAME call resolves, because the skill is materialized before the automation is validated. Filed separately, the second proposal fails — the first has not been approved yet.
64
+
65
+ Refs, not ids. To change a pending plan, **revise it** (full updated operations, re-validated). Never file a second proposal pointing at items still pending in the first.
66
+
67
+ **Budget is per proposal, not per object.** An agent has a cap on how many proposals may sit pending at once. Fourteen objects as fourteen proposals can exhaust it and get the next write refused; the same fourteen as one plan costs one slot. If a write is ever refused for the cap, that refusal carries a link to raise it — follow the link, do not retry the write. Retrying is worse than waiting: a refused write that you re-send through another door is how the same playbook ends up in the pod twice.
68
+
69
+ Do **not** declare every provides/consumes/trigger edge in the opening. Edges are a later turn, and only for the pair this work actually reads.
70
+
71
+ Do **not** invent CLI (`synap create project --evidenceEntityIds`, `synap marketplace install`, `synap declare workspace source`). Use the MCP/Hub tools this door actually exposes.
72
+
73
+ Empty workspace ≠ broken. An empty Finance is fine until this intent needs a revenue number.
74
+
75
+ ### 2b. When the work needs a CAPABILITY (a verb an automation calls)
76
+
77
+ A plan creates instruction skills, automations and rules. **A plan never installs a capability.** Installing one fetches a template from the Control Plane mid-apply, writes secrets and vault grants, and has no undo path — none of which belongs inside an all-or-none batch. Capability access is its own decision, on purpose.
78
+
79
+ Walk this ladder instead. Every rung is a door that exists; do not invent one.
80
+
81
+ | Situation | Do this |
82
+ | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
+ | Not sure the verb exists | `synap_list_capabilities` (a `query` reaches the folded builtin verbs too) |
84
+ | Verb exists but is **not enabled** | **Just run it** — `synap_run_capability`. The refusal files ONE enable request covering your whole pack and hands it back as `enableProposal`, and tells you the action did NOT run. There is no enable tool to call. |
85
+ | Verb is not installed | `market.search` to find it, then `market.install` — both builtin verbs through `synap_run_capability`. For an agent this ALWAYS files a `capability.install` proposal; that is success, not refusal. |
86
+ | The tool does not exist at Synap at all | `tool.request` (builtin verb) — records a `tool_request` so the gap is visible instead of silently blocking you |
87
+ | Authoring a reusable PACK | Declare the need as a package dependency (`relation: "require"`) rather than installing inside the pack |
88
+
89
+ **Author the automation LAST.** An automation whose `capability` node names a verb that is not in the catalog is rejected at author time (`capability_unknown_verbId`) — the write never lands, so there is nothing half-built to clean up. Get the verb enabled or installed first, then file the plan that uses it.
90
+
91
+ A skill your plan creates IS resolvable in the same batch: the automation door looks a verb up by **skill name**, and skills materialize before automations. That is why a fact + a behaviour can ride in one proposal.
92
+
93
+ ### 2c. A lasting goal inside a project → a TRACK
94
+
95
+ A **track** is a lasting intent with a goal inside ONE project ("Grow the newsletter", "Win the first ten clients"); a project runs several. It holds a `direction` (one line, in the person's words) and, only if the person names a number, a `kpi` `{ label, unit?, target }`. It lasts: it is paused or archived, never "finished" for hitting a number. Work in it is ordinary sessions filed into it. Definitions: `concepts`.
96
+
97
+ **Asked to pursue a goal in a project** ("keep growing the newsletter in Synap"): `synap_list_tracks` for the project (already running? resume it) → none? `synap_start_track` with `projectId`, a `name`, the `direction` and any `kpi` the person named — no method needed. Then work: `synap_start_session` with `trackId`, one session per sitting, as many as it takes.
98
+
99
+ | The user needs… | Do this |
100
+ | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------- |
101
+ | a **lasting goal** in an existing project | `synap_list_tracks` (already running?) → `synap_start_track` (`name`, `direction`, optional `kpi`) |
102
+ | one piece of work toward it | a **session** born in the track: `synap_start_session` (or `synap_run_playbook` for a session template) with `trackId` |
103
+ | a repeatable way to do that work | a session template (`synap_create_playbook`, default scope) run with `trackId` — not a track method |
104
+ | new **kinds of things** no workspace owns | a workspace (four-test, `workspace-design`) — never to represent a track |
105
+ | a new long-lived commitment with its own gravity | a project — never a twin project for a track of an existing one |
106
+
107
+ **A track steers; its sessions verify.** Report progress with `synap_update_track` `kpi: { current }`: a STATED value, stamped with when and by whom — never invent a measurement. Reaching the target nudges the person to re-aim it; never change the target yourself. While a track is active, its agent may work in the spaces its project links (`synap_project_use_workspace`); pausing it suspends that, archiving ends it. Pause, resume or archive it with `synap_set_track_status`. Track writes are governed: `proposed` is success. Installing a pack onto a project does **not** start tracks — start each one.
108
+
109
+ **Legacy: tracks with stages.** A track started from a track template (`scope: "project"`, `playbookId` on `synap_start_track`) has re-enterable stages. Work a stage with `synap_start_stage_session` (`trackId`, optional `stageKey`); never `synap_advance_track` without the user — advancing returns an `offer` (show it, start it only on a yes). Do not create new track templates; a new track needs none.
110
+
111
+ ### 3. Which skill to load next
112
+
113
+ | Need | Skill |
114
+ | -------------------------------------------- | ---------------------------------------------------------- |
115
+ | Schema: facet, overlay, child kind, new kind | `system/synap-schema/extend-first` then `extend-vs-create` |
116
+ | Missing operational domain | `system/agent-os/skill` |
117
+ | Views / cards once the model exists | `system/synap-ui/skill` |
118
+ | What a word means (the one glossary) | `system/synap/concepts` |
119
+ | Lenses, gravity, sessions | `system/synap/lenses` |
120
+ | Four-test for a workspace | `system/synap/workspace-design` |
121
+ | Index of everything | `catalog` |
122
+
123
+ ### Firewalls (never)
124
+
125
+ - Twin **project**: orient already has this company/commitment under another name.
126
+ - Twin kind/role whose **slug or display name** matches `list_profiles`.
127
+ - A 7-step "right sequence" in the first confirm. One structural move per turn.
128
+ - **Splitting one coherent structure into N proposals.** If the objects reference each other, they are ONE plan through `synap_capture`, not one `create_*` call each. N cards the reviewer must mentally re-join is the failure this conductor exists to prevent.
129
+ - Building structure with no session open. The unit of work is named first (§0.4) or the work arrives as orphan proposals.
130
+ - Grading yourself. "85% complete" against no criteria and no declared outputs is an opinion, not a status — propose criteria (§0.4) and expected outputs (§2) so the person can check the claim.
131
+ - Onboard or fill an empty workspace "because it is empty."
132
+ - Invent a workspace that fails the four-test.
133
+ - Nested or twin projects, or a workspace, to represent a **goal or method** of an existing project. A lasting goal is a track; a repeatable method is a playbook a session or worker follows; one bounded piece of work is a session (`trackId`).
134
+ - Invent CLI flags or tools this door does not list.
135
+ - A second entity for a hat (`kind_mismatch` → **widen** the role’s `applicableKinds`, then `attach_facet`).
136
+ - Company/person-only facets. If the hat belongs on `item` (or any kind), the role’s `applicableKinds` must include that kind.
137
+ - CRM `deal` (pre-sale pipeline) as a generic price timeline. A commercial snapshot with its own life uses the **deal precedent** (own kind), not a twin `deal` slug and not JSON on the thing.
138
+ - Encoding the pattern only as Knowledge and expecting every MCP agent to find it. Skills + this conductor are the all-pods path.
139
+
140
+ ### After it works
141
+
142
+ Offer L4, one at a time: session → work template; cell → renderer; **project → pack** (a `suite`) (`synap_export_project_pack` / CLI `--from-project`). Export returns a thin suite **plus** full constituent workspace packages — publish constituents first, then the suite (CLI does both). Install with `projectName` (human) or `projectId` (agent) to mint/reuse a named engagement and stamp uses-edges. Optional `projectSurface` lands in `projects.settings.layout` (engagement UI). Not live entity rows. Never crystallize a guess. No `app` package type.
@@ -36,17 +36,17 @@ Changed: [field] [old value] → [new value]
36
36
 
37
37
  ```
38
38
  Context: User asked to track the Acme deal they mentioned in today's call.
39
- Intent: Creates a deal entity for Acme at lead stage linked to Alice Johnson.
39
+ Intent: Creates a deal entity for Acme at draft stage linked to Alice Johnson.
40
40
  Links: ent_person_alice_johnson, ent_company_acme
41
41
  ```
42
42
 
43
43
  **Example (update):**
44
44
 
45
45
  ```
46
- Context: User confirmed the Acme deal moved to proposal stage.
46
+ Context: User confirmed the Acme proposal went out.
47
47
  Intent: Advances the deal through the pipeline so it appears in the proposal view.
48
48
  Links: ent_deal_acme, ent_person_alice_johnson
49
- Changed: dealStage lead → proposal
49
+ Changed: commercialStage draft → proposed
50
50
  ```
51
51
 
52
52
  Rules:
@@ -59,6 +59,6 @@ Example response to the user:
59
59
 
60
60
  > I queued **Delete task "Q2 plan review"** for your review. Destructive actions need your approval. Open it: synap://open/proposal/prp_abc
61
61
 
62
- Auto-approved by default (for agent API keys): `entity.create`, `entity.update`, `document.create`, `relation.create`, `view.create`, `profile.create`, `property_def.create`, `channel.create`, `memory.*`, all reads. Destructive actions (`delete`, `archive`, `purge`) always propose in agent-owned workspaces.
62
+ Auto-approved by default (for agent API keys): `entity.create`, `entity.update`, `document.create`, `relation.create`, `view.create`, `channel.create`, `memory.*`, all reads. META-MODEL writes (`profile.*`, `property_def.*` — new kinds, roles and fields) always propose: they are pod-wide and have no inert state to land in. Destructive actions (`delete`, `archive`, `purge`) always propose in agent-owned workspaces.
63
63
 
64
64
  For the full whitelist, agent-user semantics, and workspace overrides, read **`governance.md`**.
@@ -60,18 +60,20 @@ Agents can perform these actions directly without a proposal:
60
60
  - `document.create`
61
61
  - `memory.store` (always auto-approved, never proposed)
62
62
  - `view.create`
63
- - `profile.create`, `profile.update`
64
- - `property_def.create`, `property_def.update`
65
63
  - `channel.create`
66
64
  - `bento.arrange`
67
- - `filesystem.write_workspace` (OpenClaw sandbox only)
65
+ - `filesystem.write_workspace` (agent sandbox only)
68
66
 
69
67
  **Proposal-gated** (always require approval when done by agents):
70
68
 
71
69
  - `entity.delete`, `entity.archive`, `entity.purge`
72
70
  - `view.update`, `view.delete`
73
- - `profile.delete`
74
- - `property_def.delete`
71
+ - `profile.create`, `profile.update`, `profile.delete` — META-MODEL. A kind/role
72
+ is pod-wide (`entityScope` defaults to `'pod'`), so it changes what the pod IS
73
+ in every workspace. Unlike `automation.create` (auto-approved but landing
74
+ INERT as a draft), profiles have no inert state, so they propose.
75
+ - `property_def.create`, `property_def.update`, `property_def.delete` — a base
76
+ property def (`workspace_id` NULL) extends a shared kind for every workspace.
75
77
  - `workspace.create`, `workspace.update`, `workspace.delete`
76
78
 
77
79
  ## Destructive action override
@@ -108,7 +110,7 @@ You do not poll or wait. The user's experience is asynchronous.
108
110
 
109
111
  An agent user is a pod-wide user with `agentMetadata.writesRequireProposal` set. Created by `POST /api/hub/setup/agent`. Each agent user has:
110
112
 
111
- - `agentType`: a free-form string (`"claude-code"`, `"openclaw"`, `"raycast"`, `"custom"`)
113
+ - `agentType`: a free-form string (`"claude-code"`, `"codex"`, `"raycast"`, `"custom"`)
112
114
  - `agentMetadata`: arbitrary JSON for config
113
115
  - Hub API keys scoped to `hub-protocol.read` + `hub-protocol.write` + `mcp.*`
114
116
 
@@ -184,7 +186,8 @@ GET /api/hub/workspaces/{workspaceId}/governance
184
186
  effective: {
185
187
  autoApproveFor: [ // the actual whitelist at this workspace
186
188
  "entity.create", "entity.update", "relation.create", "document.create",
187
- "view.create", "profile.create", "property_def.create", "memory.*", …
189
+ "view.create", "memory.*", … // NOT profile.create / property_def.create —
190
+ // meta-model writes propose (see "Proposal-gated" above)
188
191
  ],
189
192
  governanceMode: "default" | "agent-owned",
190
193
  proposalApprovalPolicy: "owner_and_admins" | "any_editor" | "admins_only",
@@ -0,0 +1,33 @@
1
+ ## Hand work to an agent on the person's computer
2
+
3
+ The person says "start this on my devbox", "have my Mac's Claude Code do it", "give this session to Codex". You find the agent, hand it the work through a session, follow the session's room, and report back. You never run their machine yourself: an agent they connected there (`synap worker`, Claude Code, Codex) picks the work up.
4
+
5
+ **1. Find it — `synap_list_agents`.** One read: `computers[]` (the person's own) and `agents[]`, each with `computer`, `canTakeYourWork` (else `whyNot`), `live`, `paused`, `lastSeenAt`, and `handOff`: what YOUR hand-off would do right now (`direct`, `asks_you`, `blocked` + `handOffReason`). Ready agents come first.
6
+
7
+ - **Match the person's words against computer names first** ("my devbox" → the computer named `devbox`, any case), **then agent names and types** ("Codex", "claude-code"). Take the agents on that computer that can take the work.
8
+ - **Two or more fit → ask the person** which one, by name ("Claude Code on devbox, or Codex on devbox?"). Never pick for them.
9
+ - **None fits → say so.** "I see no agent on a computer called devbox" plus what you do see. Never hand it to a different machine silently.
10
+ - **`paused: true` → say it is paused** and that a person must resume it (Settings › Agents). Do not hand it off.
11
+ - **`live: false` → say when it was last seen** (`lastSeenAt`) and that it picks the work up the next time it checks in. Hand off only if the person still wants it.
12
+ - **`canTakeYourWork: false`** — `whyNot` says why: `not_owned` (another person's agent: it would never see this work), `wrong_reach` (the pod's own agent: it answers in rooms, it never picks work up), `paused`.
13
+
14
+ **2. Hand it — through a session.** The session's roster is how work reaches an agent.
15
+
16
+ - New work: `synap_start_session` with a `title`, a one-sentence `goal`, 2–5 `criteria` the person can check, and `agentIds: [agentUserId]`.
17
+ - Work in flight ("this session"): `synap_update_session` with `addAgentId: agentUserId`.
18
+ - Read the reply. `handOffs[].status` (start) or `handOff.status` (update): `granted` = on the roster now; `proposed` = waiting for the person's approval; `denied` = say the `reason` as given.
19
+ - **`asks_you` / `proposed`: the person approves the hand-off first.** Tell them plainly: "approve the hand-off on your phone", with the `reviewUrl` from the reply. It is success, do not retry. Then wait: `synap_get_session` until the agent is on its roster (or `synap_wait_for_answer` if you also asked them something), and go on to step 3.
20
+ - **`blocked` / `denied`: say why, in the reason's words.** Never retry it as is. One case the list cannot predict: your own proposal limit ("Agent proposal limit reached") — the reply carries a link to raise it; pass that to the person.
21
+
22
+ **3. Follow the room.** Everything the agent says lands in the session's room (`session.channelId`). Read it with `synap_get_thread_context { threadId: channelId }`; read the session's outcomes with `synap_get_session`. A `synap worker` on that computer follows this protocol:
23
+
24
+ - It checks for handed sessions about every 30 seconds and starts ONE run of Claude Code per session, in its working folder.
25
+ - It **claims** the session in the room in one line: picked up, and what it will do first.
26
+ - It works on a branch (`devbox/<session>-<slug>`, in a git worktree). It never pushes to main and never deploys.
27
+ - It **asks** with a room message starting `QUESTION:`. Kind `update` = you, the orchestrating AI, can answer; kind `question` = a decision only the person can make (the person is notified). It waits up to 30 minutes, reading the room every minute, and takes the FIRST reply posted after its question. No reply: it states its assumption and continues, or stops and says what is blocked.
28
+ - It **reports** in the room (what changed, branch, commit, files) and records deliverables against the session's outcomes. It does not close the session; the owner does.
29
+ - **Any room message posted after its run ended, by anyone but the agent, wakes it again** in the same conversation (up to 20 times). That is how an answer reaches it after it stopped. So post in the room only what you want it to act on.
30
+
31
+ Answer a `QUESTION:` of kind `update` yourself with `synap_post_message` to the room. Leave kind `question` to the person, or ask them and relay their answer.
32
+
33
+ **4. Report back.** Tell the person, in a few lines: which agent on which computer took it, whether it is on the roster or waiting for their approval, what the agent reported (result, branch, commit), and anything it asked that only they can answer. Point them at the session to review and close it.
@@ -8,6 +8,7 @@ When the user is interacting with Synap's AI Companion (the in-browser chat pane
8
8
  | ---------------------------- | --------------------------- | --------------------------------- |
9
9
  | `[[entity:UUID\|Name]]` | Purple entity chip | Opens entity detail in side panel |
10
10
  | `[[view:UUID\|Name]]` | Blue view chip | Opens view |
11
+ | `[[view:UUID]]` | View chip, named for you | Same; the label is optional |
11
12
  | `[[open:side\|view:UUID]]` | Amber "Open in side" button | Opens view in side panel |
12
13
  | `[[open:main\|view:UUID]]` | Amber "Open" button | Opens view in main panel |
13
14
  | `[[open:side\|entity:UUID]]` | Amber "Open in side" button | Opens entity in side panel |
@@ -16,10 +17,11 @@ When the user is interacting with Synap's AI Companion (the in-browser chat pane
16
17
 
17
18
  ### Rules
18
19
 
20
+ - **The label is optional.** `[[kind:UUID]]` is valid: in a document the chip shows the object's current name; in chat, where nothing looks it up, it reads as its kind ("View"). So in a chat reply, write the name you know: `[[view:UUID|Active Tasks]]`. A chip never shows the raw id.
19
21
  - **Always use real IDs.** Never hallucinate UUIDs. Only emit patterns for entities/views you just created or retrieved via Hub Protocol.
20
22
  - **Emit after creation.** When you create a view or entity, immediately reference it: `"Created your pipeline → [[view:abc123|Active Tasks]]"`
21
23
  - **Prefer side panel.** Use `[[open:side|view:UUID]]` so the user keeps their current context.
22
- - **Only in Companion replies.** These patterns are silently ignored in non-companion channels, documents, and memory. Do not use them there.
24
+ - **Companion replies and documents.** In a document, `[[entity:…|…]]` / `[[view:…|…]]` render as chips and the editor keeps them (`document-embeds.md`); the `[[open:…]]` / `[[run:…]]` commands are chat-only. Other channels and memory ignore them.
23
25
  - **Combine with prose.** Don't lead with a chip — embed it naturally: `"Here are your open deals → [[view:xyz|Deals Pipeline]] · [[open:side|view:xyz]]"`
24
26
 
25
27
  ### Proposals
@@ -28,11 +30,17 @@ There is no `[[open:…|proposal:…]]` chip — `open`'s `resourceType` only ac
28
30
  `entity`, `view`, `doc`, `cell`, `channel`. A proposal is not one of those, so
29
31
  never invent that form.
30
32
 
31
- When a write returns `status: "proposed"`, the response also carries a
32
- `reviewUrl` (a full Synap Studio URL). Surface it as a plain markdown link, and
33
- add one sentence explaining why the write was proposed instead of auto-applied:
33
+ When a write returns `status: "proposed"` (or any per-op outcome carrying a
34
+ `reviewUrl` — `writeReceipt.reviewUrl`, `perm.reviewUrl`, a capability run's
35
+ `kind: "proposed"`), the response also carries that `reviewUrl` (a real,
36
+ resolvable `${PUBLIC_URL}/open/<id>` link — never invented). **Surfacing it is
37
+ MANDATORY, not optional:** every reply that reports a proposed write MUST
38
+ include the link as a plain markdown link, plus one sentence explaining why it
39
+ was proposed instead of auto-applied:
34
40
 
35
- > Queued the task deletion for your review — destructive actions always need approval: [Review proposal](https://pod.example.com/proposals/prp_abc)
41
+ > Queued the task deletion for your review — destructive actions always need approval: [Review proposal](https://pod.example.com/open/prp_abc)
36
42
 
37
- `"proposed"` is normal, not an error — don't apologize for it or wait for the
38
- user to approve before continuing the conversation.
43
+ A reply that only says "I've proposed that for review" with no link is
44
+ incomplete — the user has no way to act on it. `"proposed"` is normal, not an
45
+ error — don't apologize for it or wait for the user to approve before
46
+ continuing the conversation.
@@ -2,18 +2,35 @@
2
2
 
3
3
  You don't work "inside a workspace" the way you'd work inside a folder. You operate **across the whole pod**, and you **focus** through up to three composable lenses. **Lenses narrow; they never silo.** Omitting them is legal and common — that's pod-wide.
4
4
 
5
- | Lens | What it is | How to set (this session) |
6
- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------ |
7
- | **Project** | a **company or initiative** — the thing that ties the work together (Synap, a client, a launch). The lens you usually _organize by_. | `synap project use <id>` / `clear` |
8
- | **Workspace** | an **operational domain** — where data lives (Foundation, CRM, Marketing, Finance, Builder). How the work is separated; the default home for writes. | `synap use <name-or-id>` |
9
- | **Session** | the **work room** for the current goal (holds goal, deliverables, progress) | `synap session start --goal "…"` / `attach <id>` |
5
+ Tool names below are stems; your door may prefix them.
10
6
 
11
- **How they compose — this is the whole model:**
7
+ What each word means (workspace, project, track, step, work): `concepts` — the one glossary. This file is only about scoping.
12
8
 
13
- - A **project spans workspaces**: one company/initiative has a Foundation, a CRM, a Marketing, a Finance… each a different operational lens on the _same_ project.
14
- - A **workspace spans projects**: the Marketing workspace can hold work for several clients/projects at once.
15
- - **Membership is per-entity, filed on write.** An entity belongs to a project because it was created/filed **under the project lens** — not because its workspace is "in" the project (there is no workspace→project link). So **set the project lens before writing** work that belongs to an initiative, and it composes into that project from any workspace.
16
- - Compose either way, or both. That's why they're lenses, not folders: **workspaces exist so that development, finance, marketing, and operations don't pile into one undifferentiated place** — they're the separation that makes the work legible.
9
+ | Lens | Scopes | Set it (MCP / CLI) |
10
+ | ------------- | ---------------------------------------------------------- | ------------------------------------------------------------------ |
11
+ | **Workspace** | a domain; a thing lives in exactly ONE; default write home | `set_workspace_focus` / `synap use <name-or-id>` |
12
+ | **Project** | a commitment across workspaces; a thing can be in several | `set_project_focus` or `projectId` / `synap project use <id>` |
13
+ | **Session** | the work room for the current goal; pass its id on writes | `start_session` / `synap session start --goal "…"` / `attach <id>` |
14
+
15
+ **The project rule (one rule, every door):** a project is set ONLY when the user names it — declare it with `set_project_focus`, or pass `projectId` on the write. Filing into a project shares entities and documents with its members (a session is shared only through its room, never by filing), so never infer one from content, and never let a session decide it: a write without a `sessionId` is grouped into YOUR session — the one you started, else one opened for you, never another client's — and that door-picked session never sets the project. When nobody named a project, leave it unset. Guessing a workspace is merely untidy; guessing a project is not.
16
+
17
+ **One space per domain — the lens rule (every door):** A space is a domain, installed once (Content, Brand, CRM…). A project is a filter across spaces. To make something “for project X”: file it into X inside the domain's space (`file_into_project`), and link X to the space (`project_use_workspace`). Never create a space named after a project, a brand or a client. A second space from a template whose domain already has a live space is refused for an agent (`status: "exists"` + the space to use); a person may still create one, with the same note.
18
+
19
+ **Reads:** pod-wide by default; find by name, id or role, and pass `workspaceId` / `projectId` only to narrow a list.
20
+
21
+ **Writes:** name the kind (profile slug) and, when known, the roles as facets. Omit `workspaceId` unless you are deliberately pinning a domain — the server places the write from installed profile metadata. Never invent a workspace name. Focus sticks for the session; an explicit `workspaceId` / `projectId` on one call overrides it for that call.
22
+
23
+ **Empty domains:** a workspace holding 0 entities is a scaffold — prefer an active one unless the user names it (`orient` lists active domains; `detail:'full'` shows every one).
24
+
25
+ **Where the kinds are:** `orient` names the kinds in use, most-used first; the profile-listing tool lists every kind and role. A kind's property schema (fields, enums, required): over MCP, `get_entity` on any existing entity of that kind returns it as `effectiveProperties`; over HTTP, `GET /api/hub/discover?profileSlugs=<slug>`; CLI `synap discover`. A write that breaks the schema is rejected with the valid fields quoted.
26
+
27
+ **The space brief — what a space is FOR, and what it KNOWS.** PIN a space and the pod hands you its **brief**: `purpose` + `persona` (what it is for), `keyKinds` (the kinds it holds), `rules`, `playbooks`, `anchors`, and — the one that changes how you work — **`skills`**: the agent know-how the space ACTIVATES, each `{ slug, mode, when? }`. Reach it by passing a `workspaceId` to `orient` (an unpinned orient carries NO brief — it is space-scoped), or by `set_workspace_focus`; its reply carries the same brief. **Read the mode:** `mode: 'always'` is in effect for every task in this space — `load_skill` its slug before you work; `mode: 'on-demand'` means load it when the task matches its `when`. A space's skills are the pod telling you _this domain has a way of doing things_ — honour them rather than improvising. Pin the space the moment you are about to work in one.
28
+
29
+ **How they compose** (definitions: `concepts`):
30
+
31
+ - A **project spans workspaces** and a **workspace spans projects**.
32
+ - **Membership is per-entity, filed on write.** An entity belongs to a project because it was written **under that project lens** (`belongs_to_project`) — that is the data ACL/filing edge. Separately, provisioning with a `projectId` also stamps **`project --uses--> workspace`**: an INDEX of domains the engagement runs through. That index is **not** an ACL and does **not** replace entity filing — set the project lens before writing work so entities compose into the project from any workspace.
33
+ - A lasting goal inside a project is a **track**, never a child project or a workspace; a bounded piece of work is a **session** (`trackId` when it belongs to a track). There are no nested projects.
17
34
 
18
35
  - **The connection is pod-wide by design.** Your MCP/CLI link is _not_ welded to a workspace — reads default pod-wide, writes default to a sensible workspace. Pass a lens to narrow a single call; the lens is a focus, not a fence.
19
36
  - **These are per-Claude-session.** Two concurrent Claude sessions can sit on different projects/workspaces/sessions without colliding. `synap use` here rebinds **this** session only.
@@ -24,15 +41,16 @@ You don't work "inside a workspace" the way you'd work inside a folder. You oper
24
41
  **Before the FIRST write of a new unit of work**, check your lens and orient if you're unsure:
25
42
 
26
43
  1. `synap lens` — am I scoped where this work belongs?
27
- 2. If unsure what exists → `synap orient` — it returns a **light lens map**: the projects and the workspaces (names + ids), so you see the shape without a data dump. Never guess IDs. Drill into a workspace's profiles or a project's contents only when you actually need them.
44
+ 2. If unsure what exists → `synap orient` — it returns the **briefing**: pending review, open sessions, the kinds in use, then the projects and workspaces (names + ids), without a data dump. Never guess IDs. Drill into a workspace's profiles or a project's contents only when you actually need them.
28
45
  3. **Connect or create:** if the right project / workspace / session doesn't exist yet, create it. A **session is the normal per-task move**. Creating a **workspace (a new operational domain) is a deliberate, expected move as the work grows** — not something to avoid. A **project, though, is a COMMITMENT WITH GRAVITY**: search existing projects first (`synap orient`) and prefer **linking into an existing one** via `belongs_to_project`. Only create a new project for a real initiative that ties work together — never for a task, plan, repo, or theme (those are entities), and **never for the pod owner's own company** (the company _is_ the pod, not a project inside it). An agent-created project must cite **≥5 existing entities** as evidence or the backend rejects it, and near-duplicate names are rejected with the existing candidates.
29
46
 
30
47
  **Don't re-orient mid-flow.** Once you've oriented and you're in a run of related writes, keep going — re-check only when you **start a new piece of work** or switch domains. The reflex guards the _start_ of work, not every call.
31
48
 
32
- ### Notice a missing domain — and offer it
49
+ ### Notice a missing method or domain — and offer it
33
50
 
34
- Because workspaces are how a company separates its operations, a project is sometimes **missing an operational domain it clearly needs**. If the conversation is squarely about an area — sales, content, finance, hiring, ops — and the active project has **no workspace for it**, say so **once, at the end, in one line**, and offer to set it up:
51
+ A project sometimes clearly needs something it lacks. Tell the two apart first:
35
52
 
36
- > _"This project doesn't have a Marketing workspace yet — want me to spin one up and capture the essentials?"_
53
+ - **A lasting goal is missing** (the talk keeps returning to a goal — growing the newsletter, landing clients… — and `list_tracks` shows no track for it) → offer a **track**: _"This project has no track for the newsletter yet — want me to start one?"_ Then `start_track` with a `name` and `direction`; no method needed.
54
+ - **A domain is missing** (new kinds of things must be recorded that no workspace owns — e.g. you are logging deals and there is no CRM) → offer a **workspace**, provisioned with the project lens active (see the `agent-os` skill). Never a workspace to stand for a method.
37
55
 
38
- If they say yes, provision that **one** domain and run its onboarding interview **with the project lens active** (so its entities file into the project) (see the `agent-os` skill — it handles both the whole-company setup and adding a single domain to an existing project). **Offer, don't auto-build.** One nudge per response, and only when the gap is real — never a checklist of everything the project "could" have. **If the user has already declined a domain (this session or before), drop it — don't re-offer.**
56
+ Say it **once, at the end, in one line**. **Offer, don't auto-build.** One nudge per response, only when the gap is real — never a checklist of everything the project "could" have. **If the user has already declined it (this session or before), drop it — don't re-offer.**
@@ -8,17 +8,14 @@ When a profile property has `valueType: "entity_id"`, setting it on entity creat
8
8
 
9
9
  Known system-profile auto-syncs:
10
10
 
11
- | Profile | Property | Target profile | Auto-relation type |
12
- | -------- | ----------- | -------------- | -------------------- |
13
- | task | `projectId` | project | `belongs_to_project` |
14
- | task | `assignee` | person | `assigned_to` |
15
- | contact | `companyId` | company | `works_at` |
16
- | deal | `contactId` | contact | `deal_for` |
17
- | deal | `companyId` | company | `deal_with` |
18
- | document | `entityId` | (any) | `attached_to` |
19
- | anchor | `channelId` | (channel) | `anchored_in` |
20
-
21
- Custom profiles: if you created a property with `valueType: "entity_id"`, the auto-sync kicks in, but the relation type defaults to `related_to` unless the profile defines a `relationDefinition`. When precision matters, create the relation explicitly (Way 2) with a specific `type`.
11
+ | Profile | Property | Target profile | Auto-relation type |
12
+ | ------- | ----------- | -------------- | -------------------- |
13
+ | task | `projectId` | project | `belongs_to_project` |
14
+ | task | `assignee` | person | `assigned_to` |
15
+ | contact | `companyId` | company | `works_at` |
16
+ | deal | `contactId` | contact | `deal_for` |
17
+
18
+ Custom profiles: an `entity_id` property does NOT create an edge on its own. Auto-sync writes a relation only when the property def is mapped to a relation def (its `relationDefId`), and the edge then takes THAT def's slug. An unmapped `entity_id` property stores the id and creates no relation at all — there is no default or fallback type. When you need the edge, create it explicitly (Way 2) with an existing relation-def slug; `synap_list_profiles` returns them under `relationTypes`.
22
19
 
23
20
  **Do not trust this table to stay current.** Always verify with `GET /api/hub/profiles` — the returned profile includes `properties[].valueType` and `properties[].targetProfileSlug`. Any property with `valueType: "entity_id"` is an auto-sync candidate.
24
21
 
@@ -68,37 +65,40 @@ POST /api/hub/relations
68
65
  }
69
66
  ```
70
67
 
71
- ## Conventional relation types
72
-
73
- String-typed, case-insensitive by convention. Use these first before inventing new ones — workspace UI often renders known types specially.
74
-
75
- | Type | Direction | When |
76
- | -------------- | --------------- | ------------------------------------------------- |
77
- | `related_to` | bidirectional | Generic association, no stronger label fits |
78
- | `parent_of` | source → target | Hierarchy (project parent of sub-project) |
79
- | `child_of` | source → target | Hierarchy (inverse of parent_of) |
80
- | `belongs_to` | source → target | Membership |
81
- | `authored_by` | source → target | Note/document authored by a person |
82
- | `depends_on` | source → target | Task blocked by another task, project needs input |
83
- | `references` | source → target | Task references a document, note cites an article |
84
- | `mentions` | source → target | Entity mentioned within another entity |
85
- | `works_with` | bidirectional | People who collaborate |
86
- | `part_of` | source → target | Component relationship |
87
- | `from_meeting` | source → target | Any entity extracted from a meeting/event |
88
- | `anchored_in` | source → target | Anchor (pinned chat message) in a channel |
89
-
90
- If none fits, invent a snake_case verb. Keep it short and symmetric with existing verbs. Don't create `related-to-this-specific-thing` — prefer a generic `related_to` plus a more specific property or document.
68
+ ## Relation types — use the pod's, never invent one
69
+
70
+ A relation's `type` must be the slug of a relation definition the pod has. `synap_list_profiles` returns them under `relationTypes` (custom ones a workspace added included) — read it before linking. The defaults every pod ships:
71
+
72
+ | Type | Direction | When |
73
+ | ------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
74
+ | `relates_to` | bidirectional | Generic association, when no stronger type fits |
75
+ | `references` | source → target | A task references a document, a note cites an article |
76
+ | `mentions` | source → target | One entity is mentioned within another's content |
77
+ | `links_to` | source → target | A hyperlink or explicit pointer |
78
+ | `parent_of` | source → target | Entity hierarchy (a kind instance of another). Not nested projects — those do not exist. A method in a project is a track; a unit of work is a session. |
79
+ | `belongs_to_project` | source → target | An entity filed into a project (prefer the `projectId` property — Way 1) |
80
+ | `assigned_to` | source → target | A task/project assigned to a person |
81
+ | `created_by` | source → target | A note/document authored or created by a person |
82
+ | `blocks` / `depends_on` | source → target | A DEPENDENCY: the source blocks / waits on the target. Dependencies are becoming ONE `blocked_by` edge across kinds (session · entity · track); these two slugs are its entity-side names |
83
+ | `tagged_with` | source → target | Categorization by a tag entity |
84
+ | `attended_by` | source → target | An event's participant |
85
+ | `works_at` · `works_on` · `affiliated_with` | source → target | A person and an organization / a project they contribute to / an affiliation |
86
+ | `knows` · `met_at` · `discussed_with` | person → target | People who know each other / where they met / who they talked with |
87
+ | `deal_for` | source → target | A sales deal for a contact |
88
+ | `has_skill` | source → target | A person's skill |
89
+
90
+ **No fitting type? Do not invent one.** A slug that is not a relation definition is refused or lands as a link nobody can read. Use `relates_to` plus a more specific property or document, or — if the relationship recurs and deserves a name — propose a new relation definition (it is a schema change, reviewed like one).
91
91
 
92
92
  ## Decision table
93
93
 
94
- | Situation | Use |
95
- | ------------------------------------------------------ | -------------------------------------- |
96
- | Profile has matching `valueType: "entity_id"` property | Way 1 — set the property |
97
- | Linking two already-existing entities | Way 2 — create a relation |
98
- | Custom connection, no matching property | Way 2 |
99
- | Unsure whether a property exists | `GET /profiles` first |
100
- | Linking a document to its parent entity | Use `entityId` on the document (Way 1) |
101
- | Multi-party link (entity A ↔ entity B ↔ entity C) | Two relations, both Way 2 |
94
+ | Situation | Use |
95
+ | ------------------------------------------------------ | ------------------------- |
96
+ | Profile has matching `valueType: "entity_id"` property | Way 1 — set the property |
97
+ | Linking two already-existing entities | Way 2 — create a relation |
98
+ | Custom connection, no matching property | Way 2 |
99
+ | Unsure whether a property exists | `GET /profiles` first |
100
+ | Linking a document to the entity it is about | Way 2 — `references` |
101
+ | Multi-party link (entity A ↔ entity B ↔ entity C) | Two relations, both Way 2 |
102
102
 
103
103
  ## Reading the graph
104
104
 
@@ -125,5 +125,6 @@ GET /api/hub/graph/traverse?entityId={id}&maxDepth=2
125
125
  - **Spinning up a new project instead of linking into an existing one.** A project is a **commitment with gravity**, not a folder for a task, plan, repo, or theme (those are entities). Before `create_project`, search existing projects and file the entity into one via `belongs_to_project` (Way 1 `projectId`, or Way 2 relation). Near-duplicate project names are rejected server-side with the existing candidates, and an agent-created project also requires **≥5 existing entities** as evidence.
126
126
  - **Creating an orphan, then forgetting to link it.** Every `POST /entities` should include properties that link, OR be immediately followed by a `POST /relations`. Never close the operation with a disconnected node.
127
127
  - **Double-linking.** If you set `properties.projectId` AND also `POST /relations` with type `belongs_to_project`, the auto-sync already did it. Don't duplicate.
128
- - **Using `related_to` when a specific verb fits.** `related_to` is the fallback. `authored_by`, `depends_on`, `references` carry more meaning to both the user and downstream views.
128
+ - **Using `relates_to` when a specific type fits.** `relates_to` is the fallback. `created_by`, `depends_on`, `references` carry more meaning to both the user and downstream views.
129
+ - **Inventing a relation type.** `child_of`, `belongs_to`, `authored_by`, `part_of`, `works_with` are NOT relation types here — use `parent_of` (from the parent), `belongs_to_project`, `created_by`, `parent_of` / `relates_to`, `knows`. Check `relationTypes` first.
129
130
  - **Inverting direction.** Source is "the thing doing the action or owning the relationship." `task depends_on task` means the source is blocked by the target. Check twice.
@@ -0,0 +1,64 @@
1
+ # Remote MCP servers — how a pod registers, approves and governs them
2
+
3
+ Load this before you suggest connecting an external MCP server to a pod, or when a server's tools do not
4
+ show up. Every claim here is read from the code: the `mcp_servers` table
5
+ (`packages/database/src/schema/mcp-servers.ts`), the settings door (`routers/mcp-servers.ts`), the
6
+ capability installer (`services/capabilities/create-from-definition.ts`) and the IS adapter.
7
+
8
+ ### The row
9
+
10
+ One row per server in `mcp_servers`, scoped to a space (`workspaceId`) or pod-wide (null). `slug` is
11
+ lowercase `a-z0-9-`, unique per space; the IS names each tool `mcp_<slug>_<tool>`, so a space's server
12
+ overrides a pod-wide one with the same slug.
13
+
14
+ | Field | Meaning |
15
+ | ------------ | ------------------------------------------------------------------------------------------ |
16
+ | `transport` | `http` (needs `url`) or `stdio` (needs `command` + `args`, runs on the IS host) |
17
+ | `auth` | http only: `{ credentialRef: "vault://<id>", header: "Authorization", prefix: "Bearer " }` |
18
+ | `toolPolicy` | `{ default: "governed" or "inline", inline: ["tool_a", …] }`; absent = governed |
19
+ | `approved` | false by default; the supply-chain gate |
20
+ | `enabled` | the owner's on/off switch |
21
+
22
+ ### Secrets never sit on the row
23
+
24
+ `auth.credentialRef` points at a vault secret. The pod resolves it server-side on every call (never
25
+ cached), sends it to the IS as a header, and the agent never sees it. If it cannot be resolved for the
26
+ acting user or agent, the server is skipped and its tools simply do not appear: check the vault grant
27
+ before you blame the server.
28
+
29
+ ### Governed by default
30
+
31
+ - A **governed** tool is never called directly: the IS routes it through the pod (`mcp://<slug>`),
32
+ where the capability gate runs it or files a proposal. For an agent, `proposed` is success.
33
+ - An **inline** tool is called directly by the IS. Declare `default: "inline"` only for a server that
34
+ exposes nothing but reads; for a mixed server, list its read tools in `inline`.
35
+ - No policy at all means governed. This is deliberate and fail-closed.
36
+
37
+ ### Approval, and when it resets
38
+
39
+ - Tools reach an agent only when the server is **approved AND enabled** (and, in a channel that keeps
40
+ its own MCP list, only the servers that channel opted into). The list is cached for 30 seconds.
41
+ - In the space settings, tab MCP Servers: a space **owner or admin** adds, edits or deletes a server; only the space
42
+ **owner** approves it; a pod-wide server needs a pod admin to add or edit.
43
+ - Editing `url`, `command`, `args`, `env` or `transport` in the settings **resets approval** (compared by
44
+ value, so a rename or an enabled toggle does not). Re-approve after re-pointing a server.
45
+ - A capability (catalog or `market.install`) may declare `mcpServers[]` with `auth` and `toolPolicy`;
46
+ this is the only door that sets those two today (the settings form does not). Its install is the trust
47
+ decision: it may ship `approved: true`. Re-applying it converges url, auth and policy to the
48
+ template and only ever promotes approval, never revokes it.
49
+
50
+ ### As an agent
51
+
52
+ You have no tool that registers a server. Propose it: a capability that declares the server (installed
53
+ through `market.install`, which files a proposal), or ask the person to add it in the space settings (MCP Servers). Never
54
+ ask for the secret in chat; it goes in the vault.
55
+
56
+ ### Network: who must reach the URL
57
+
58
+ The **IS** opens the connection, not your machine. A `url` must be reachable from where the pod's IS runs.
59
+
60
+ **An unauthenticated dev MCP is never registered on a public URL.** Storybook's `/mcp`
61
+ (`http://localhost:6006/mcp`) and similar dev servers have no auth: reach them only over a private
62
+ network or a tunnel the IS is on (an SSH tunnel to a dev pod), keep them bound to loopback otherwise,
63
+ and prefer a static artifact (Storybook's `/manifests/components.json`) for agents on a remote pod. If
64
+ a server would need to be public to be reached, it needs `auth` first.