@synap-core/cli 1.8.0 → 1.10.0

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 (332) hide show
  1. package/dist/commands/agent-chat.d.ts +47 -0
  2. package/dist/commands/agent-chat.js +250 -0
  3. package/dist/commands/agent-chat.js.map +1 -0
  4. package/dist/commands/agent-run.js +3 -4
  5. package/dist/commands/agent-run.js.map +1 -1
  6. package/dist/commands/agents.js +85 -46
  7. package/dist/commands/agents.js.map +1 -1
  8. package/dist/commands/automation.js +2 -1
  9. package/dist/commands/automation.js.map +1 -1
  10. package/dist/commands/bridge-setup.d.ts +66 -0
  11. package/dist/commands/bridge-setup.js +1112 -0
  12. package/dist/commands/bridge-setup.js.map +1 -0
  13. package/dist/commands/cap-connections.d.ts +28 -0
  14. package/dist/commands/cap-connections.js +224 -0
  15. package/dist/commands/cap-connections.js.map +1 -0
  16. package/dist/commands/capability.d.ts +89 -0
  17. package/dist/commands/capability.js +1523 -0
  18. package/dist/commands/capability.js.map +1 -0
  19. package/dist/commands/centrality.d.ts +20 -0
  20. package/dist/commands/centrality.js +94 -0
  21. package/dist/commands/centrality.js.map +1 -0
  22. package/dist/commands/connect.d.ts +2 -0
  23. package/dist/commands/connect.js +16 -35
  24. package/dist/commands/connect.js.map +1 -1
  25. package/dist/commands/context.js +4 -6
  26. package/dist/commands/context.js.map +1 -1
  27. package/dist/commands/data-extra.d.ts +1 -0
  28. package/dist/commands/data-extra.js +34 -10
  29. package/dist/commands/data-extra.js.map +1 -1
  30. package/dist/commands/data.d.ts +4 -4
  31. package/dist/commands/data.js +241 -184
  32. package/dist/commands/data.js.map +1 -1
  33. package/dist/commands/diagnose.d.ts +20 -0
  34. package/dist/commands/diagnose.js +143 -0
  35. package/dist/commands/diagnose.js.map +1 -0
  36. package/dist/commands/digest.d.ts +17 -0
  37. package/dist/commands/digest.js +121 -0
  38. package/dist/commands/digest.js.map +1 -0
  39. package/dist/commands/discover.d.ts +2 -0
  40. package/dist/commands/discover.js +25 -8
  41. package/dist/commands/discover.js.map +1 -1
  42. package/dist/commands/events.js +2 -1
  43. package/dist/commands/events.js.map +1 -1
  44. package/dist/commands/explain.d.ts +1 -1
  45. package/dist/commands/explain.js +18 -15
  46. package/dist/commands/explain.js.map +1 -1
  47. package/dist/commands/facet.d.ts +29 -0
  48. package/dist/commands/facet.js +113 -0
  49. package/dist/commands/facet.js.map +1 -0
  50. package/dist/commands/graph.js +2 -1
  51. package/dist/commands/graph.js.map +1 -1
  52. package/dist/commands/import.d.ts +38 -0
  53. package/dist/commands/import.js +440 -0
  54. package/dist/commands/import.js.map +1 -0
  55. package/dist/commands/init.js +35 -16
  56. package/dist/commands/init.js.map +1 -1
  57. package/dist/commands/keys.js +3 -4
  58. package/dist/commands/keys.js.map +1 -1
  59. package/dist/commands/knowledge.d.ts +2 -0
  60. package/dist/commands/knowledge.js +61 -9
  61. package/dist/commands/knowledge.js.map +1 -1
  62. package/dist/commands/launch.d.ts +50 -0
  63. package/dist/commands/launch.js +790 -0
  64. package/dist/commands/launch.js.map +1 -0
  65. package/dist/commands/lens.d.ts +45 -0
  66. package/dist/commands/lens.js +386 -0
  67. package/dist/commands/lens.js.map +1 -0
  68. package/dist/commands/market.d.ts +209 -0
  69. package/dist/commands/market.js +1368 -0
  70. package/dist/commands/market.js.map +1 -0
  71. package/dist/commands/mcp.d.ts +42 -0
  72. package/dist/commands/mcp.js +184 -0
  73. package/dist/commands/mcp.js.map +1 -0
  74. package/dist/commands/observe.js +14 -11
  75. package/dist/commands/observe.js.map +1 -1
  76. package/dist/commands/open.d.ts +21 -4
  77. package/dist/commands/open.js +45 -4
  78. package/dist/commands/open.js.map +1 -1
  79. package/dist/commands/pod.d.ts +100 -0
  80. package/dist/commands/pod.js +359 -0
  81. package/dist/commands/pod.js.map +1 -0
  82. package/dist/commands/pods.d.ts +1 -0
  83. package/dist/commands/pods.js +77 -15
  84. package/dist/commands/pods.js.map +1 -1
  85. package/dist/commands/proposals-actions.js +40 -3
  86. package/dist/commands/proposals-actions.js.map +1 -1
  87. package/dist/commands/purge.d.ts +23 -0
  88. package/dist/commands/purge.js +148 -0
  89. package/dist/commands/purge.js.map +1 -0
  90. package/dist/commands/raycast.d.ts +15 -0
  91. package/dist/commands/raycast.js +153 -0
  92. package/dist/commands/raycast.js.map +1 -0
  93. package/dist/commands/sessions.js +45 -21
  94. package/dist/commands/sessions.js.map +1 -1
  95. package/dist/commands/skill-manage.d.ts +21 -0
  96. package/dist/commands/skill-manage.js +195 -0
  97. package/dist/commands/skill-manage.js.map +1 -0
  98. package/dist/commands/skills-commands.js +2 -1
  99. package/dist/commands/skills-commands.js.map +1 -1
  100. package/dist/commands/skills.js +4 -3
  101. package/dist/commands/skills.js.map +1 -1
  102. package/dist/commands/status.d.ts +3 -1
  103. package/dist/commands/status.js +166 -14
  104. package/dist/commands/status.js.map +1 -1
  105. package/dist/commands/statusline.d.ts +24 -0
  106. package/dist/commands/statusline.js +450 -0
  107. package/dist/commands/statusline.js.map +1 -0
  108. package/dist/commands/subscribe.js +2 -2
  109. package/dist/commands/subscribe.js.map +1 -1
  110. package/dist/commands/tools.d.ts +30 -0
  111. package/dist/commands/tools.js +315 -0
  112. package/dist/commands/tools.js.map +1 -0
  113. package/dist/commands/versions.d.ts +27 -0
  114. package/dist/commands/versions.js +277 -0
  115. package/dist/commands/versions.js.map +1 -0
  116. package/dist/commands/view.js +3 -2
  117. package/dist/commands/view.js.map +1 -1
  118. package/dist/commands/whoami.d.ts +21 -0
  119. package/dist/commands/whoami.js +129 -0
  120. package/dist/commands/whoami.js.map +1 -0
  121. package/dist/index.js +776 -60
  122. package/dist/index.js.map +1 -1
  123. package/dist/lib/approval-poll.d.ts +42 -0
  124. package/dist/lib/approval-poll.js +52 -0
  125. package/dist/lib/approval-poll.js.map +1 -0
  126. package/dist/lib/auth.d.ts +29 -6
  127. package/dist/lib/auth.js +105 -94
  128. package/dist/lib/auth.js.map +1 -1
  129. package/dist/lib/bundle-version.d.ts +11 -0
  130. package/dist/lib/bundle-version.js +33 -0
  131. package/dist/lib/bundle-version.js.map +1 -0
  132. package/dist/lib/capture-lane.d.ts +30 -12
  133. package/dist/lib/capture-lane.js +71 -14
  134. package/dist/lib/capture-lane.js.map +1 -1
  135. package/dist/lib/cp-packages.d.ts +121 -0
  136. package/dist/lib/cp-packages.js +218 -0
  137. package/dist/lib/cp-packages.js.map +1 -0
  138. package/dist/lib/describe-lens.d.ts +46 -0
  139. package/dist/lib/describe-lens.js +33 -0
  140. package/dist/lib/describe-lens.js.map +1 -0
  141. package/dist/lib/hub-client.d.ts +78 -1
  142. package/dist/lib/hub-client.js +474 -22
  143. package/dist/lib/hub-client.js.map +1 -1
  144. package/dist/lib/installed.d.ts +51 -0
  145. package/dist/lib/installed.js +70 -0
  146. package/dist/lib/installed.js.map +1 -0
  147. package/dist/lib/next-steps.d.ts +61 -0
  148. package/dist/lib/next-steps.js +146 -0
  149. package/dist/lib/next-steps.js.map +1 -0
  150. package/dist/lib/pod.d.ts +91 -19
  151. package/dist/lib/pod.js +222 -56
  152. package/dist/lib/pod.js.map +1 -1
  153. package/dist/lib/project-ref.d.ts +95 -0
  154. package/dist/lib/project-ref.js +144 -0
  155. package/dist/lib/project-ref.js.map +1 -0
  156. package/dist/lib/project.d.ts +35 -0
  157. package/dist/lib/project.js +39 -0
  158. package/dist/lib/project.js.map +1 -0
  159. package/dist/lib/session-lens.d.ts +33 -0
  160. package/dist/lib/session-lens.js +76 -0
  161. package/dist/lib/session-lens.js.map +1 -0
  162. package/dist/lib/skill-import.d.ts +40 -0
  163. package/dist/lib/skill-import.js +203 -0
  164. package/dist/lib/skill-import.js.map +1 -0
  165. package/dist/lib/skills-installer.d.ts +17 -6
  166. package/dist/lib/skills-installer.js +133 -19
  167. package/dist/lib/skills-installer.js.map +1 -1
  168. package/dist/lib/suite.d.ts +28 -0
  169. package/dist/lib/suite.js +29 -0
  170. package/dist/lib/suite.js.map +1 -0
  171. package/dist/lib/superwhisper-import.d.ts +40 -0
  172. package/dist/lib/superwhisper-import.js +389 -0
  173. package/dist/lib/superwhisper-import.js.map +1 -0
  174. package/dist/lib/targets.d.ts +49 -1
  175. package/dist/lib/targets.js +420 -288
  176. package/dist/lib/targets.js.map +1 -1
  177. package/dist/lib/unwrapList.d.ts +1 -0
  178. package/dist/lib/unwrapList.js +20 -0
  179. package/dist/lib/unwrapList.js.map +1 -0
  180. package/dist/utils/logger.d.ts +2 -0
  181. package/dist/utils/logger.js +10 -2
  182. package/dist/utils/logger.js.map +1 -1
  183. package/package.json +9 -4
  184. package/skills/agent-os/SKILL.md +212 -0
  185. package/skills/manifest.json +5 -0
  186. package/skills/onboard/SKILL.md +186 -0
  187. package/skills/synap/SKILL.md +1182 -37
  188. package/skills/synap/_order.txt +37 -0
  189. package/skills/synap/_skill.yaml +24 -0
  190. package/skills/synap/authentication.md +10 -0
  191. package/skills/synap/automations.md +264 -0
  192. package/skills/synap/capabilities.md +107 -0
  193. package/skills/synap/capture.md +10 -0
  194. package/skills/synap/cli-operations.md +107 -0
  195. package/skills/synap/common-mistakes.md +12 -0
  196. package/skills/synap/creative-loop.md +43 -0
  197. package/skills/synap/crm.md +117 -0
  198. package/skills/synap/diagnostics.md +35 -0
  199. package/skills/synap/digesting-a-channel.md +38 -0
  200. package/skills/synap/document-embeds.md +123 -0
  201. package/skills/synap/escalation-ladder.md +71 -0
  202. package/skills/synap/focus-sessions.md +47 -0
  203. package/skills/synap/governance-rules.md +64 -0
  204. package/skills/synap/governance.md +6 -6
  205. package/skills/synap/graph-gardening.md +21 -0
  206. package/skills/synap/inline-patterns.md +38 -0
  207. package/skills/synap/lenses.md +38 -0
  208. package/skills/synap/linking-principle.md +39 -0
  209. package/skills/synap/linking.md +1 -0
  210. package/skills/synap/mental-model.md +45 -0
  211. package/skills/synap/more.md +7 -0
  212. package/skills/synap/multi-entity-capture.md +10 -0
  213. package/skills/synap/next-action.md +37 -0
  214. package/skills/synap/north-star.md +17 -0
  215. package/skills/synap/operating-mode-rules.md +45 -0
  216. package/skills/synap/operating-mode.md +9 -0
  217. package/skills/synap/quick-reference.md +67 -0
  218. package/skills/synap/reading.md +43 -0
  219. package/skills/synap/recap.md +21 -0
  220. package/skills/synap/reflexes.md +46 -0
  221. package/skills/synap/response-style.md +21 -0
  222. package/skills/synap/scope.md +13 -0
  223. package/skills/synap/showing.md +17 -0
  224. package/skills/synap/user-model.md +25 -0
  225. package/skills/synap/viewframe-cells.md +290 -0
  226. package/skills/synap/work-flow.md +113 -0
  227. package/skills/synap/worked-examples.md +53 -0
  228. package/skills/synap/workspace-design.md +45 -0
  229. package/skills/synap/workspace-edges.md +49 -0
  230. package/skills/synap/writes.md +156 -0
  231. package/skills/synap-schema/SKILL.md +97 -6
  232. package/skills/synap-schema/_order.txt +13 -0
  233. package/skills/synap-schema/_skill.yaml +22 -0
  234. package/skills/synap-schema/before-you-touch.md +14 -0
  235. package/skills/synap-schema/common-mistakes.md +9 -0
  236. package/skills/synap-schema/creating-profiles.md +17 -0
  237. package/skills/synap-schema/discover-profiles.md +24 -0
  238. package/skills/synap-schema/entity-scope.md +8 -0
  239. package/skills/synap-schema/extend-vs-create.md +31 -0
  240. package/skills/synap-schema/more.md +6 -0
  241. package/skills/synap-schema/overlay-properties.md +22 -0
  242. package/skills/synap-schema/profiles.md +3 -0
  243. package/skills/synap-schema/property-defs.md +29 -0
  244. package/skills/synap-schema/read-before-write.md +50 -0
  245. package/skills/synap-schema/relations.md +18 -0
  246. package/skills/synap-schema/worked-example.md +30 -0
  247. package/skills/synap-ui/SKILL.md +26 -2
  248. package/skills/synap-ui/_order.txt +13 -0
  249. package/skills/synap-ui/_skill.yaml +23 -0
  250. package/skills/synap-ui/ai-companion.md +27 -0
  251. package/skills/synap-ui/arranging-bento.md +8 -0
  252. package/skills/synap-ui/before-you-build.md +20 -0
  253. package/skills/synap-ui/bento-layouts.md +35 -0
  254. package/skills/synap-ui/common-mistakes.md +10 -0
  255. package/skills/synap-ui/creating-views.md +26 -0
  256. package/skills/synap-ui/four-builds.md +24 -0
  257. package/skills/synap-ui/more.md +7 -0
  258. package/skills/synap-ui/proposing-vs-extending.md +11 -0
  259. package/skills/synap-ui/view-list.md +24 -0
  260. package/skills/synap-ui/views.md +3 -0
  261. package/skills/synap-ui/worked-example.md +18 -0
  262. package/skills/synap-ui/workspaces.md +47 -0
  263. package/templates/automations/bookmark-enrichment.automation.json +44 -0
  264. package/templates/automations/mail-feed.automation.json +86 -0
  265. package/templates/automations/url-bookmark-capture.automation.json +70 -0
  266. package/templates/skills/README.md +21 -0
  267. package/templates/skills/authoring-automations/SKILL.md +95 -0
  268. package/templates/skills/authoring-automations/reference/node-matrix.md +49 -0
  269. package/templates/skills/authoring-capabilities/SKILL.md +93 -0
  270. package/templates/skills/authoring-capabilities/reference/template-anatomy.md +70 -0
  271. package/templates/skills/authoring-playbooks/SKILL.md +102 -0
  272. package/templates/skills/authoring-playbooks/reference/stages-contract.md +35 -0
  273. package/templates/skills/authoring-playbooks/reference/worked-example.md +64 -0
  274. package/templates/skills/bookmark-enrichment/SKILL.md +40 -0
  275. package/templates/skills/coordinating-agents/SKILL.md +32 -0
  276. package/templates/skills/coordinating-branches/SKILL.md +27 -0
  277. package/templates/skills/mapping-the-server/SKILL.md +54 -0
  278. package/templates/skills/reading-client-progress/SKILL.md +65 -0
  279. package/templates/skills/routing-to-channels/SKILL.md +54 -0
  280. package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-CHEATSHEET.md +133 -0
  281. package/templates/skills/stellar-scf-grants-advisor/ASSOCIATE-ONBOARDING-GUIDE.md +761 -0
  282. package/templates/skills/stellar-scf-grants-advisor/CLIENT-FAQ.md +181 -0
  283. package/templates/skills/stellar-scf-grants-advisor/PARTNER-HANDOVER.md +130 -0
  284. package/templates/skills/stellar-scf-grants-advisor/SKILL.md +102 -0
  285. package/templates/skills/stellar-scf-grants-advisor/examples/README.md +43 -0
  286. package/templates/skills/stellar-scf-grants-advisor/examples/chat-summary-templates.md +158 -0
  287. package/templates/skills/stellar-scf-grants-advisor/examples/corpus-comparable-rows.md +136 -0
  288. package/templates/skills/stellar-scf-grants-advisor/examples/q10-team-rewrites.md +109 -0
  289. package/templates/skills/stellar-scf-grants-advisor/examples/q2-description-rewrites.md +88 -0
  290. package/templates/skills/stellar-scf-grants-advisor/examples/q6-integration-rewrites.md +107 -0
  291. package/templates/skills/stellar-scf-grants-advisor/examples/tranche-structures.md +176 -0
  292. package/templates/skills/stellar-scf-grants-advisor/reference/01-methodology.md +96 -0
  293. package/templates/skills/stellar-scf-grants-advisor/reference/02-scoring-framework.md +199 -0
  294. package/templates/skills/stellar-scf-grants-advisor/reference/03-rejection-patterns.md +241 -0
  295. package/templates/skills/stellar-scf-grants-advisor/reference/04-winner-patterns.md +120 -0
  296. package/templates/skills/stellar-scf-grants-advisor/reference/05-comeback-patterns.md +92 -0
  297. package/templates/skills/stellar-scf-grants-advisor/reference/06-budget-benchmarks.md +125 -0
  298. package/templates/skills/stellar-scf-grants-advisor/reference/07-integration-list.md +147 -0
  299. package/templates/skills/stellar-scf-grants-advisor/reference/08-abstract-fields.md +258 -0
  300. package/templates/skills/stellar-scf-grants-advisor/reference/09-build-fields.md +259 -0
  301. package/templates/skills/stellar-scf-grants-advisor/reference/10-corpus-winners.md +135 -0
  302. package/templates/skills/stellar-scf-grants-advisor/reference/11-corpus-rejects.md +267 -0
  303. package/templates/skills/stellar-scf-grants-advisor/reference/12-client-communication.md +131 -0
  304. package/templates/skills/stellar-scf-grants-advisor/reference/13-excel-output-spec.md +199 -0
  305. package/templates/skills/stellar-scf-grants-advisor/reference/14-worked-examples.md +160 -0
  306. package/templates/skills/stellar-scf-grants-advisor/templates/abstract-review-builder.py +253 -0
  307. package/templates/skills/stellar-scf-grants-advisor/templates/build-review-builder.py +213 -0
  308. package/dist/commands/connectors.d.ts +0 -31
  309. package/dist/commands/connectors.js +0 -276
  310. package/dist/commands/connectors.js.map +0 -1
  311. package/dist/commands/finish.d.ts +0 -25
  312. package/dist/commands/finish.js +0 -274
  313. package/dist/commands/finish.js.map +0 -1
  314. package/dist/commands/openclaw.d.ts +0 -40
  315. package/dist/commands/openclaw.js +0 -1148
  316. package/dist/commands/openclaw.js.map +0 -1
  317. package/dist/commands/security-audit.d.ts +0 -12
  318. package/dist/commands/security-audit.js +0 -100
  319. package/dist/commands/security-audit.js.map +0 -1
  320. package/dist/lib/hardening.d.ts +0 -18
  321. package/dist/lib/hardening.js +0 -214
  322. package/dist/lib/hardening.js.map +0 -1
  323. package/node_modules/@synap/hub-rest-client/dist/index.cjs +0 -881
  324. package/node_modules/@synap/hub-rest-client/dist/index.d.cts +0 -907
  325. package/node_modules/@synap/hub-rest-client/dist/index.d.ts +0 -907
  326. package/node_modules/@synap/hub-rest-client/dist/index.js +0 -851
  327. package/node_modules/@synap/hub-rest-client/package.json +0 -45
  328. package/node_modules/@synap/hub-rest-client/src/client.ts +0 -1143
  329. package/node_modules/@synap/hub-rest-client/src/errors.ts +0 -30
  330. package/node_modules/@synap/hub-rest-client/src/index.ts +0 -111
  331. package/node_modules/@synap/hub-rest-client/src/setup.ts +0 -77
  332. package/node_modules/@synap/hub-rest-client/src/types.ts +0 -639
@@ -0,0 +1,117 @@
1
+ ## CRM Workspaces — 4-Entity Model
2
+
3
+ Some workspaces use a CRM data structure with four entities: `person` and `company` (identity records), `deal` (pipeline record), and `client` (post-win relationship marker). Understand this pattern when proposing lead captures, deal updates, or campaign membership.
4
+
5
+ **The model:**
6
+
7
+ - **`person` + `company`** — Identity only, no sales state. Persist across deals.
8
+ - **`deal`** — Pipeline record with `dealStage` property (lead, contacted, qualifying, proposal, negotiating, won, lost, inactive). Represents what people often call a "lead" (when stage=lead). Linked to person/company via `linked_to_deal` relation.
9
+ - **`client`** — Post-win relationship marker. Created automatically when deal transitions to stage=won. Status: active, paused, or churned. Linked via `is_client` (party → client) and `produced_by_deal` (deal → client).
10
+ - **`journey`** — Documents anchored to a deal (not a person). Linked via `has_journey`.
11
+
12
+ **AI behavior — lead capture:**
13
+
14
+ When the user describes a lead (inbound person, prospect, or company lead), propose the full bundle:
15
+
16
+ 1. Create `person` entity (if not exists) with email, role, company name
17
+ 2. Create `company` entity (if not exists)
18
+ 3. Create `deal` entity with `dealStage: "lead"` and `estimatedValue` (if known)
19
+ 4. Create `linked_to_deal` relation connecting person/company to deal
20
+
21
+ Never create a person with a sales-state flag. The deal is the lead container.
22
+
23
+ ```json
24
+ POST /api/hub/entities
25
+ { "userId": "{userId}", "workspaceId": "{wsId}",
26
+ "profileSlug": "person",
27
+ "title": "Alice Johnson",
28
+ "properties": { "email": "alice@acme.com", "role": "VP Engineering" }
29
+ }
30
+
31
+ POST /api/hub/entities
32
+ { "userId": "{userId}", "workspaceId": "{wsId}",
33
+ "profileSlug": "deal",
34
+ "title": "Acme prospect",
35
+ "properties": { "dealStage": "lead", "estimatedValue": 50000 }
36
+ }
37
+
38
+ POST /api/hub/relations
39
+ { "userId": "{userId}",
40
+ "sourceEntityId": "ent_person_alice",
41
+ "targetEntityId": "ent_deal_acme",
42
+ "type": "linked_to_deal"
43
+ }
44
+ ```
45
+
46
+ **AI behavior — moving deals to won:**
47
+
48
+ When a deal transitions to `dealStage: "won"`, also propose client creation if not yet linked:
49
+
50
+ ```json
51
+ PATCH /api/hub/entities/ent_deal_acme
52
+ { "properties": { "dealStage": "won" } }
53
+
54
+ POST /api/hub/entities
55
+ { "userId": "{userId}", "workspaceId": "{wsId}",
56
+ "profileSlug": "client",
57
+ "title": "Acme (active)",
58
+ "properties": { "clientStatus": "active" }
59
+ }
60
+
61
+ POST /api/hub/relations
62
+ { "userId": "{userId}",
63
+ "sourceEntityId": "ent_person_alice",
64
+ "targetEntityId": "ent_client_acme",
65
+ "type": "is_client"
66
+ }
67
+
68
+ POST /api/hub/relations
69
+ { "userId": "{userId}",
70
+ "sourceEntityId": "ent_deal_acme",
71
+ "targetEntityId": "ent_client_acme",
72
+ "type": "produced_by_deal"
73
+ }
74
+ ```
75
+
76
+ **AI behavior — campaign membership:**
77
+
78
+ When the user describes campaign members (segment for outreach, tracking, or automation), use polymorphic `member_of` relations. Members can be persons, companies, or deals:
79
+
80
+ ```json
81
+ POST /api/hub/relations
82
+ { "userId": "{userId}",
83
+ "sourceEntityId": "ent_person_alice",
84
+ "targetEntityId": "ent_campaign_enterprise",
85
+ "type": "member_of"
86
+ }
87
+
88
+ // Same relation type, different entity type
89
+ POST /api/hub/relations
90
+ { "userId": "{userId}",
91
+ "sourceEntityId": "ent_deal_acme",
92
+ "targetEntityId": "ent_campaign_enterprise",
93
+ "type": "member_of"
94
+ }
95
+ ```
96
+
97
+ **Property names:**
98
+
99
+ - `dealStage` (not `crmStatus` or `status`) — values: lead, contacted, qualifying, proposal, negotiating, won, lost, inactive
100
+ - `clientStatus` (post-win only) — values: active, paused, churned
101
+ - Identities (person, company) carry no sales state
102
+
103
+ **Why separate identity from state:**
104
+
105
+ This model enables renewals (new deal linking to existing client), multi-stakeholder deals (multiple `linked_to_deal` relations per deal), campaigns with mixed entity types (persons + companies + deals as members), and clean churn tracking. It matches Synap's core pattern: entities + relations = graph.
106
+
107
+ ## Resolution discipline — resolve BEFORE you create
108
+
109
+ Extracting people/companies from a digest, an email/DM thread, or notes is a RESOLUTION problem, not a creation problem. Follow this method every time (it is generic — the specific team roster and known aliases are DATA you fetch, never hardcoded):
110
+
111
+ 1. **Search first, once (batched).** Before proposing any person/company, run a SINGLE batched query (`search_unified`, plus `list_entities` if needed) that covers ALL candidate names, handles, emails and aliases at once. Never run one query per candidate — that is a cost failure.
112
+ 2. **Reuse on match → add an alias.** If a candidate matches an existing entity, reference the existing entity by its real id (e.g. `existingEntityId` on `propose_entity_graph`) and add the newly-seen surface form (a handle, an alternate spelling) to the entity's `aliases` — do NOT create a second `person`/`company`. The `person` profile carries `email`, `discord-handle` and `aliases` for exactly this.
113
+ 3. **Never placeholder.** Never mint an entity whose identity is unstated — "Not publicly disclosed", "unknown", "TBD", an empty name, or a bare handle with no person behind it. Fold that unstated thing into the description of a related entity instead.
114
+ 4. **Team is not a contact.** Internal senders — your own side of a `client-comms` thread (the agency's own team) — are NEVER captured as the client's contacts. Only the external party becomes a person/company/deal. Team roster may appear in `orient.teamRoster` — treat as internal.
115
+ 5. **Connect the graph.** Every entity you propose should attach via at least one relation (person `works_at` company, person `linked_to_deal` deal, …). A name mentioned only in passing, with no relation and no stated identity, is not worth capturing as its own entity.
116
+
117
+ An extraction that creates a duplicate "Sarah Chen", or a `person` titled "Unknown sender", is a failure — resolve, reuse, and alias instead.
@@ -0,0 +1,35 @@
1
+ # Diagnosing what an AI did — the runs door
2
+
3
+ When a capture, automation, playbook, or session **didn't do what you (or the user) expected** — a facet wasn't attached, an entity landed in the wrong workspace, a step failed silently — do **not** guess or apologize. Every AI run leaves a trace. Read it.
4
+
5
+ ## The one tool
6
+
7
+ `synap_diagnose` — the unified view of what an AI did across flows.
8
+
9
+ - **No args** → the recent run feed (automation · playbook · capture · session), newest first. Each run has an `id`, `flowType`, `status`, and `flowName`.
10
+ - **`runId` + `flowType`** → that run's **activity timeline**. For a **capture** run this is its decision + trace events: for each thing that was dropped/coerced, a machine-readable `reason` **and an actionable `fixHint`**.
11
+
12
+ (CLI equivalent for the operator: `synap diagnose` and `synap diagnose <captureId> --flow capture`.)
13
+
14
+ ## The reflex
15
+
16
+ > "The capture didn't attach the client role" → `synap_diagnose({ runId: <captureId>, flowType: "capture" })` → read the `capture_trace` rows → act on the `fixHint`.
17
+
18
+ A capture's `id` **is** its correlationId — the same id stamped on the entities it created and returned to you as `captureId`. So you always have the key to diagnose your own last capture.
19
+
20
+ ## Reading a capture trace
21
+
22
+ Each `capture_trace` activity item names a pipeline stage (`component`), why it stopped (`reason`), and what to do (`fixHint`). The common ones:
23
+
24
+ | reason | what happened | what to do |
25
+ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
26
+ | `not_in_creatable_catalog` | a role/kind you asked to create isn't a creatable entity kind — it's a **facet** (client, partner, prospect, investor…) | resolve the real entity first, then `attach_facet` for the role — never a second entity for a hat |
27
+ | `kind_mismatch` | the facet's `applicableKinds` didn't include the target entity's kind | attach the role to an entity of a kind the role applies to |
28
+ | `slug_coerce` | a profileSlug was normalized/renamed to the canonical one | use the canonical slug next time (see `list_profiles`) |
29
+ | `materialize_skip` | an operation was skipped (dedup or a missing dependency) | check the dedup match; re-capture only what's genuinely new |
30
+
31
+ If a run carries a `channelId` (playbook / session / automation), its message-level story lives in that channel — the timeline points you there rather than duplicating it.
32
+
33
+ ## Why this matters
34
+
35
+ The point of the flywheel is that mistakes are **visible and fixable**, not silent. If you can see what happened, you can correct it — and every correction teaches the routing. Reach for `synap_diagnose` before you conclude "it didn't work."
@@ -0,0 +1,38 @@
1
+ # digesting-a-channel
2
+
3
+ You are digesting a chat channel — reading a window of human messages and deciding what, if anything, is worth the team's attention. You are an ADVISOR, not a bookkeeper. Surface signal; do not log every message into the database.
4
+
5
+ ## What a digest is for
6
+
7
+ Read the whole window, then answer one question: **what here genuinely matters to the team?** A decision that got made, an ask with a deadline, a new opportunity, a link worth keeping, a task someone implicitly took on, a shift in a live piece of work. Most channel chatter is noise — greetings, banter, thinking-out-loud. If nothing rises above noise, say so and stop. An honest "nothing to surface" beats a wall of manufactured entities.
8
+
9
+ ## Structure signal into whatever shape actually fits
10
+
11
+ Do NOT assume this channel is a CRM. Do NOT reach for a contacts/notes/links template by reflex. Look at the signal and pick the Synap shape that truly matches it:
12
+
13
+ - an **idea** or **decision** — a direction the team settled on, an ask, a scope change
14
+ - a **website / link / resource** worth keeping
15
+ - a **deal** or **partner** — a real new opportunity or relationship (only if that is genuinely what surfaced)
16
+ - a **task** — a concrete next action someone owns, with a due date if one was stated
17
+ - an **advancement on a workflow / playbook** — a stage moved or a step completed on work already live in the pod
18
+
19
+ `list_profiles` first when you are unsure what shapes exist. Match the signal to the shape; never force the signal into a shape you had already decided on.
20
+
21
+ ## Resolve identity before you create
22
+
23
+ Every person, company, deal, or resource you are about to propose may already exist. Resolve first, create only what is new. Match on STRONG signals — email, phone, url, handle — not a fuzzy name. Run ONE batched search over all candidates, reuse on match (add the newly-seen handle or spelling as an alias), and mint an entity only for something genuinely absent. The full resolve → reuse → alias discipline in `crm.md` applies here verbatim.
24
+
25
+ ## Role-aware people guard (read this twice)
26
+
27
+ WHO is in the channel changes what a person IS. Get this wrong and you propose your own teammates as leads.
28
+
29
+ - **Internal channel** (`branchPurpose` = `team`): every human here is OUR teammate. Never propose a teammate as a client, lead, prospect, or contact. Surface what they DECIDED or COMMITTED to — not who they are.
30
+ - **Client channel** (`branchPurpose` = `client…`): the channel mixes client-side people with our own team who also post there. Separate the two. Only genuine client-side people become the client company's contacts; our teammates in the thread stay teammates and are never attached to the client.
31
+
32
+ When a person's side is unclear, ask or leave them out — do not guess a client relationship into existence.
33
+
34
+ ## Output
35
+
36
+ Return a short, scannable digest: the few things worth attention, each with your advice or a status read ("decided X", "Y is waiting on you", "this deal moved to negotiating"). Lead with what matters most; skip the exhaustive recap.
37
+
38
+ Everything you propose goes through governance — you PROPOSE, you do not force. A `proposed` result is the system working, not a failure. If nothing crossed the bar, a one-line "nothing worth capturing from this window" is the correct and complete answer.
@@ -0,0 +1,123 @@
1
+ ## Document embeds — live entities/views/cells inside markdown
2
+
3
+ Documents (`type: "markdown"`) can embed **live, rendering** Synap objects inline, not
4
+ just links. The browser's markdown engine parses a small set of remark **container
5
+ directives** and swaps them for real components — an entity card, a view, or a cell
6
+ — wherever they appear in the prose.
7
+
8
+ **This is a DOCUMENTS-only mechanism.** It is unrelated to the `[[kind:id|label]]`
9
+ inline chips described in `inline-patterns.md` — those render **only** in Companion
10
+ chat replies. Never put a `:::synap-*` directive in a chat reply, and never put a
11
+ `[[…]]` chip in a document's `content`. Different surface, different grammar.
12
+
13
+ ### Syntax
14
+
15
+ <!-- brief:start -->
16
+
17
+ A container directive: three colons, the directive name, `{attrs}` on the opening
18
+ line, three colons alone on the closing line.
19
+
20
+ ```
21
+ :::synap-entity{id="ent_abc123"}
22
+ :::
23
+ ```
24
+
25
+ | Directive | Required attrs | Optional attrs | Renders |
26
+ | -------------- | --------------------------------------------- | -------------- | ------------------------------------------------- |
27
+ | `synap-entity` | `id` (entity UUID) | — | Compact entity card (`__entity-block` cell) |
28
+ | `synap-view` | `viewId` (view UUID) | — | Embedded, read-only view (`__embedded-view` cell) |
29
+ | `synap-cell` | `instanceId` **OR** (`cellKey` + `cellProps`) | — | A persisted cell instance, or an inline cell ref |
30
+
31
+ Only real IDs from prior tool results — never invent one. This is a
32
+ DOCUMENTS-only grammar: never use it in a chat reply, and never use a
33
+ `[[kind:id|label]]` chip inside a document's `content`.
34
+
35
+ <!-- brief:end -->
36
+
37
+ For `synap-cell`: an explicit `instanceId` always wins if present — it renders a
38
+ persisted cell instance from `/api/hub/cells`. Otherwise the pair `cellKey` +
39
+ `cellProps` builds an inline ref (`cellRefFromLegacy`). `cellProps` is a JSON string,
40
+ e.g. `cellProps='{"profileSlug":"task"}'`.
41
+
42
+ When you write a document's `content` directly (via `synap_create_document` /
43
+ `POST /api/hub/documents`), you're writing raw markdown text — quote `cellProps`'
44
+ JSON with single quotes (`cellProps='{"profileSlug":"task"}'`) so the inner `"`
45
+ characters don't collide with the directive's own `key="value"` quoting; the
46
+ markdown renderer (remark-directive) parses this directly, no escaping needed.
47
+
48
+ One caveat: if a human later opens the document in the rich-text editor, its
49
+ Tiptap round-trip serializer re-emits every directive as `key="value"` and
50
+ **drops any attribute value containing `"` or `}`** (it would otherwise corrupt
51
+ the directive) — so an inline `cellProps` blob can be silently lost on the next
52
+ editor save. For a cell you expect to survive editing, create it first
53
+ (`synap_create_cell` / `POST /api/hub/cells`) and embed it by `instanceId`
54
+ instead of inlining `cellProps`.
55
+
56
+ ### Rules
57
+
58
+ - **Only real IDs from prior tool results.** Never invent an entity/view/instance
59
+ ID. Create or look it up first (`synap_create_entity`, `synap_get_entities`,
60
+ `synap_create_view`, `synap_create_cell`), then embed the ID you got back.
61
+ - **Embeds are for DOCUMENTS.** The `[[…]]` inline chips are for Companion chat
62
+ replies. Do not mix the two grammars across surfaces.
63
+ - **Embed vs. link:** embed when the reader benefits from seeing the live
64
+ object in place — a stat card inside a report, the linked meeting entity inside
65
+ meeting notes, a pipeline view inside a status update. Link (`entities WHERE
66
+ documentId = ?` attachment, or a plain reference to the ID) when you just need
67
+ traceability and the reader doesn't need to see it rendered inline — most
68
+ documents should still be _attached_ to one entity (see `writes.md`) regardless
69
+ of whether they also embed others inline.
70
+ - A directive with a missing/invalid required attribute renders a visible error
71
+ block in the browser (`Error: View ID is required` / `Error: Cell type is
72
+ required`) — always double-check the ID before writing the directive.
73
+
74
+ ### Worked example 1 — meeting notes embedding the meeting entity
75
+
76
+ ```json
77
+ POST /api/hub/documents
78
+ {
79
+ "userId": "{userId}",
80
+ "workspaceId": "{workspaceId}",
81
+ "title": "Meeting notes — 2026-07-12",
82
+ "type": "markdown",
83
+ "entityId": "ent_event_kickoff",
84
+ "content": "# Kickoff meeting\n\n:::synap-entity{id=\"ent_event_kickoff\"}\n:::\n\n## Decisions\n- Ship the pilot by August 1\n\n## Action items\n- [ ] Draft the rollout plan"
85
+ }
86
+ ```
87
+
88
+ The event entity renders as a live card at the top of the notes — attendees,
89
+ time, status stay current even if the entity changes later.
90
+
91
+ ### Worked example 2 — status report embedding a pipeline view
92
+
93
+ ```json
94
+ POST /api/hub/documents
95
+ {
96
+ "userId": "{userId}",
97
+ "workspaceId": "{workspaceId}",
98
+ "title": "Weekly deals update",
99
+ "type": "markdown",
100
+ "entityId": "ent_project_eve",
101
+ "content": "# Weekly update\n\nThree deals moved to negotiating this week.\n\n:::synap-view{viewId=\"view_deals_pipeline\"}\n:::\n\nSee the board above for the live state."
102
+ }
103
+ ```
104
+
105
+ ### Worked example 3 — report embedding an inline stat cell
106
+
107
+ ```json
108
+ POST /api/hub/documents
109
+ {
110
+ "userId": "{userId}",
111
+ "workspaceId": "{workspaceId}",
112
+ "title": "Q2 task summary",
113
+ "type": "markdown",
114
+ "entityId": "ent_project_eve",
115
+ "content": "# Q2 summary\n\n:::synap-cell{cellKey=\"stat-card\" cellProps='{\"profileSlug\":\"task\"}'}\n:::\n\nOpen tasks are trending down."
116
+ }
117
+ ```
118
+
119
+ Note the mixed quoting: the directive's own attribute values use double quotes
120
+ (`cellKey="stat-card"`), so the outer `cellProps` value uses single quotes to hold
121
+ its JSON — the JSON itself must not contain any `"` once flattened into the
122
+ attribute string, or the serializer will drop it. When in doubt, prefer a
123
+ persisted `instanceId` over inline `cellProps`.
@@ -0,0 +1,71 @@
1
+ # Escalation ladder — discover → invent under proposal → crystallize after proof
2
+
3
+ The always-on brief lives in `reflexes.md`. This file is the full HOW when you need more than the corner-of-your-head reminder.
4
+
5
+ ## Why it exists
6
+
7
+ Agents fail in two ways: (1) dead-end ("I can't do that") when the substrate could express the need after discovery or a proposed meta change, and (2) silent invent (minting workspaces/profiles/views without checking what already exists). The ladder is the habit that prevents both. Soft teaching only — no hard tool filtering by tier.
8
+
9
+ ## Levels
10
+
11
+ ### L0 — Reflexes (always)
12
+
13
+ Recall before non-trivial work (`synap_ask` / search). Capture durable learning after. Treat `"proposed"` as success-in-review, not an error. Orient once per session.
14
+
15
+ ### L1 — OPERATE on data
16
+
17
+ Default mode: work with what already exists.
18
+
19
+ - Capture free text, create/update entities, link, attach **known** facets
20
+ - Start/update sessions when the work is a unit with a deliverable
21
+ - Prefer existing profiles, views, capabilities, playbooks over inventing structure
22
+
23
+ ### L2 — DISCOVER before invent
24
+
25
+ When the tool list or current schema doesn't express the need — **search before minting**:
26
+
27
+ 1. `list_profiles` / `list_views` / `list_capabilities({query})` in the active lenses
28
+ 2. `market.search({query, kind?})` over `capability` | `template` | `automation` | `cell`
29
+ 3. Load the relevant skill (`load_skill` / discover_tools) if the HOW is unclear
30
+
31
+ Only if L2 returns empty for the real need do you climb to L3.
32
+
33
+ ### L3 — MUTATE the meta-model (proposal-gated)
34
+
35
+ Extend the substrate so the need becomes expressible. Always governed — expect `"proposed"`.
36
+
37
+ | Need | Prefer | Tool sketch |
38
+ | ------------------ | -------------------- | --------------------------------------------------------------------------------------- |
39
+ | Role/hat missing | Existing role attach | `define_role` only after `list_profiles` empty for that role |
40
+ | Field missing | Existing property | `create_property_def` |
41
+ | Kind missing | Closest parent kind | `create_profile` (extend, don't fork) |
42
+ | View missing | Existing view | `list_views` first, then `create_view` (recovery or proactive) |
43
+ | Domain missing | **Template** | `market.search(kind:template)` → install/propose **before** freehand `create_workspace` |
44
+ | Capability missing | Marketplace | `market.install` (always proposes for agents) |
45
+
46
+ **Template-before-workspace (hard rule in teaching):** new operational domains start as marketplace templates when one fits. Freehand workspace creation is last resort after the four workspace-design conditions hold (`workspace-design.md`). Capture never invents a workspace — placement only routes into existing lenses.
47
+
48
+ ### L4 — CRYSTALLIZE after proof
49
+
50
+ After a one-off has succeeded and is clearly repeatable:
51
+
52
+ - Session that worked → `promote_session_to_playbook`
53
+ - Cell that presents well for a type/slot → `promote_cell_to_renderer`
54
+ - Repeatable process authored deliberately → `create_playbook`
55
+
56
+ Never crystallize a speculative or failed one-off. One structural suggestion at a time; if speculative, ask first (`creative-loop.md`).
57
+
58
+ ## Decision gates (cheat sheet)
59
+
60
+ ```
61
+ Can I do it with existing data/tools?
62
+ yes → L1
63
+ no → L2 discover
64
+ found → use / install (propose) / enable
65
+ empty → L3 propose meta change (never silent invent)
66
+ Did a one-off just succeed and will recur?
67
+ yes → offer L4 (question if speculative)
68
+ no → leave it as a one-off
69
+ ```
70
+
71
+ Blocked path: **never** invent silently; **never** stop at a dead-end error — climb L2→L3 and propose. Success path: one clear structural nudge, not a cascade of schema changes.
@@ -0,0 +1,47 @@
1
+ ## Focus Sessions — Goal-Bound Work Rooms
2
+
3
+ A **focus session** is a named, multi-step work room where you and AI agents collaborate on a specific goal. Use one whenever the work has a clear end state, will take more than one exchange, or involves multiple agents.
4
+
5
+ **When to propose a session** (via the proposal system — always ask first):
6
+
7
+ - Research with 5+ sources → decision memo
8
+ - Lead generation sprint → qualified list + outreach drafts
9
+ - Incident investigation → postmortem doc
10
+ - Data import → structured knowledge base
11
+ - Any task you'd naturally call "a project" rather than "a question"
12
+
13
+ **How the AI proposes a session:**
14
+
15
+ ```
16
+ create_proposal with targetType: "focus_session"
17
+ → user reviews goal + rationale + expected outputs in ProposalReviewBoard
18
+ → on approval, session is created in focus_sessions table
19
+ → AI updates progress (0→100) via PATCH /api/hub/focus-sessions/:id { workspaceId, progress: N }
20
+ → session auto-surfaces in the Active Sessions bento widget on the user's home
21
+ ```
22
+
23
+ **Session templates** (pass as `templateId`):
24
+ `research-room` · `lead-sprint` · `decision-memo` · `import-cleanup` · `incident-room` · `campaign-intel`
25
+
26
+ **Hub Protocol REST** (for IS → backend; always include `workspaceId`):
27
+
28
+ - `POST /api/hub/focus-sessions` — create (include `correlationId` for idempotency)
29
+ - `GET /api/hub/focus-sessions/:id?workspaceId=<id>` — read
30
+ - `PATCH /api/hub/focus-sessions/:id` — update `{ workspaceId, progress, status, goal, agentIds }`
31
+
32
+ **CLI** (use when running as Claude Code / OpenClaw agent):
33
+
34
+ ```bash
35
+ synap session start --goal "<goal>" [--workspace <id>] # create + start a session
36
+ synap session list [--workspace <id>] [--status active|paused|closed] # list sessions
37
+ synap session get <id> [--workspace <id>] # read a session
38
+ synap session update <id> --workspace <id> --progress 50 # report progress
39
+ synap session update <id> --workspace <id> --status paused # pause
40
+ synap session close <id> --workspace <id> [--recap "what was done"] # close + recap
41
+ ```
42
+
43
+ Note: `synap session start` creates a session directly (the agent-facing path). All hub-protocol writes are governance-gated server-side; the in-browser AI companion surfaces session creation through the proposal flow.
44
+
45
+ **MCP door**: after `synap_start_session` returns, call `synap_get_channel` to get a personal channel for the session, then `synap_post_message` with `triggerAI:true` to dispatch the IS agent for autonomous work on the goal. The agent's produced entities link back to the session via the graph.
46
+
47
+ **Discoverability**: the `active-sessions` bento widget is on the default home dashboard. Sessions group their related proposals under a shared `correlationId` in the Proposal Review Board.
@@ -0,0 +1,64 @@
1
+ ## Writing — governance in one paragraph
2
+
3
+ Every write returns a `status` field:
4
+
5
+ ```
6
+ "approved" → done, use { id }
7
+ "proposed" → queued for user approval; response also carries { proposalId, summary, reasoning, reviewPath, reviewUrl } — surface the link
8
+ "denied" → blocked, explain reason to user
9
+ ```
10
+
11
+ **`"proposed"` is not an error.** It's the governance system queueing your change. When you get it:
12
+
13
+ 1. Tell the user exactly what was queued — use the `summary` field **verbatim**. Don't paraphrase.
14
+ 2. Give them the link to review — `reviewUrl` opens the proposal in Synap Studio. Show the link as-is.
15
+ 3. Move on with the conversation. Don't wait or poll.
16
+
17
+ ### The `reasoning` field — required, structured, contextual
18
+
19
+ Every write call (create, update, delete) must include a `reasoning` field. This is what the governance reviewer reads to understand your decision. It is **not optional**.
20
+
21
+ Use this exact structure:
22
+
23
+ ```
24
+ Context: [what the user said or what event triggered this write — one sentence]
25
+ Intent: [what this entity or change accomplishes — one sentence]
26
+ Links: [actual entity IDs or slugs this relates to, e.g. "ent_abc, ent_xyz"]
27
+ ```
28
+
29
+ For updates, add:
30
+
31
+ ```
32
+ Changed: [field] [old value] → [new value]
33
+ ```
34
+
35
+ **Example (create):**
36
+
37
+ ```
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.
40
+ Links: ent_person_alice_johnson, ent_company_acme
41
+ ```
42
+
43
+ **Example (update):**
44
+
45
+ ```
46
+ Context: User confirmed the Acme deal moved to proposal stage.
47
+ Intent: Advances the deal through the pipeline so it appears in the proposal view.
48
+ Links: ent_deal_acme, ent_person_alice_johnson
49
+ Changed: dealStage lead → proposal
50
+ ```
51
+
52
+ Rules:
53
+
54
+ - One sentence per field. No padding.
55
+ - `Links` must reference real entity IDs or slugs visible in the current context — not descriptions like "the related project".
56
+ - **"Agent requires proposal for all write operations."** is never acceptable as a `reasoning` value. That is an internal governance message, not agent reasoning. Write it and the proposal is meaningless to the reviewer.
57
+
58
+ Example response to the user:
59
+
60
+ > I queued **Delete task "Q2 plan review"** for your review. Destructive actions need your approval. Open it: synap://open/proposal/prp_abc
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.
63
+
64
+ For the full whitelist, agent-user semantics, and workspace overrides, read **`governance.md`**.
@@ -16,7 +16,7 @@ Every write endpoint returns a `status` field. Handle all three.
16
16
  "summary": "Delete task \"Q2 plan review\"",
17
17
  "reasoning": "Destructive actions require your approval",
18
18
  "reviewPath": "/proposals/prp_…",
19
- "reviewUrl": "https://studio.synap.live/proposals/prp_…",
19
+ "reviewUrl": "synap://open/proposal/prp_…",
20
20
  "message": "…"
21
21
  }
22
22
  → Queued for user review. Surface `summary` + `reviewUrl` to the user; do not retry.
@@ -145,15 +145,15 @@ When a write is proposed, surface three things to the user: what was queued, why
145
145
  ```
146
146
  good: "I queued **Delete task \"Q2 plan review\"** for your review.
147
147
  Destructive actions need your approval.
148
- https://studio.synap.live/proposals/prp_abc"
148
+ synap://open/proposal/prp_abc"
149
149
 
150
150
  good: "I queued **Create entity \"Acme Corp\"** for your review.
151
- https://studio.synap.live/proposals/prp_def"
151
+ synap://open/proposal/prp_def"
152
152
 
153
153
  good: "Queued 3 changes for your review — I'll post the links after each:
154
- 1. https://studio.synap.live/proposals/prp_1 — Delete task "X"
155
- 2. https://studio.synap.live/proposals/prp_2 — Delete task "Y"
156
- 3. https://studio.synap.live/proposals/prp_3 — Delete task "Z""
154
+ 1. synap://open/proposal/prp_1 — Delete task "X"
155
+ 2. synap://open/proposal/prp_2 — Delete task "Y"
156
+ 3. synap://open/proposal/prp_3 — Delete task "Z""
157
157
 
158
158
  bad: "Error: write was not approved."
159
159
  bad: "Something needs your attention in Synap." ← too vague
@@ -0,0 +1,21 @@
1
+ ## Garden the graph — writes tell you their impact (the circling of action)
2
+
3
+ A write is no longer blind. When you create or update an entity, the response tells you what it did to the graph — **READ it and act**, so the graph stays connected instead of accumulating isolated, duplicated nodes.
4
+
5
+ **On create**, the response carries a `resolution` block:
6
+
7
+ - `existingSameProfile` — an entity with this exact name ALREADY exists as the same profile. Prefer **updating** it (`synap set entity <id>` · `PATCH /api/hub/entities/:id` · `update_entity`) over creating a duplicate.
8
+ - `autoConnected` — same-name entities of a DIFFERENT profile are facets of one real thing, and the system has already woven them together with a `same_subject` relation. Acknowledge it; add a more specific relation if the real relationship is narrower than "same subject".
9
+ - `suggestions` — entities worth linking. Create the relations that genuinely apply (`synap create relation` · `POST /api/hub/relations` · `create_relation`).
10
+
11
+ **On update**, the response carries an `impact` block — the entity's immediate relation neighbors. Read it and resolve secondary effects: supersede a now-stale entity, update its dependents, re-link.
12
+
13
+ **The circling of action** for any structural write (updating the vision, the architecture, a decision record, a codebase map):
14
+
15
+ 1. **Write** — the response shows collisions + connections; don't ignore it.
16
+ 2. **If it already exists** (`existingSameProfile`) → update it, don't duplicate.
17
+ 3. **The same-name facets are auto-woven** (`autoConnected`) → extend the links where the relationship is more specific than `same_subject`.
18
+ 4. **Act on `suggestions`** → link what genuinely relates.
19
+ 5. **On update** → resolve the `impact` neighbors (supersede / update / re-link).
20
+
21
+ The principle: **more data is better when it is structured.** The graph now helps you keep it structured — never leave an entity isolated, never blindly overwrite. (Matching is exact-name today; it will deepen over time — so still link deliberately when you know two things relate but their names differ.)
@@ -0,0 +1,38 @@
1
+ ## AI Inline Patterns — reference entities in your replies
2
+
3
+ When the user is interacting with Synap's AI Companion (the in-browser chat panel), you can embed **inline chips** directly in your reply text. These render as clickable buttons the user can tap to open entities, views, or documents without leaving the conversation.
4
+
5
+ ### Syntax
6
+
7
+ | Pattern | Renders as | Effect |
8
+ | ---------------------------- | --------------------------- | --------------------------------- |
9
+ | `[[entity:UUID\|Name]]` | Purple entity chip | Opens entity detail in side panel |
10
+ | `[[view:UUID\|Name]]` | Blue view chip | Opens view |
11
+ | `[[open:side\|view:UUID]]` | Amber "Open in side" button | Opens view in side panel |
12
+ | `[[open:main\|view:UUID]]` | Amber "Open" button | Opens view in main panel |
13
+ | `[[open:side\|entity:UUID]]` | Amber "Open in side" button | Opens entity in side panel |
14
+ | `[[run:UUID\|Label]]` | Green "Run" button | Navigates to automation entity |
15
+ | `[[doc:UUID\|Name]]` | Gray doc chip | Opens document |
16
+
17
+ ### Rules
18
+
19
+ - **Always use real IDs.** Never hallucinate UUIDs. Only emit patterns for entities/views you just created or retrieved via Hub Protocol.
20
+ - **Emit after creation.** When you create a view or entity, immediately reference it: `"Created your pipeline → [[view:abc123|Active Tasks]]"`
21
+ - **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.
23
+ - **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
+
25
+ ### Proposals
26
+
27
+ There is no `[[open:…|proposal:…]]` chip — `open`'s `resourceType` only accepts
28
+ `entity`, `view`, `doc`, `cell`, `channel`. A proposal is not one of those, so
29
+ never invent that form.
30
+
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:
34
+
35
+ > Queued the task deletion for your review — destructive actions always need approval: [Review proposal](https://pod.example.com/proposals/prp_abc)
36
+
37
+ `"proposed"` is normal, not an error — don't apologize for it or wait for the
38
+ user to approve before continuing the conversation.
@@ -0,0 +1,38 @@
1
+ ## Lenses — where you are vs. what you can reach
2
+
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
+
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>` |
10
+
11
+ **How they compose — this is the whole model:**
12
+
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.
17
+
18
+ - **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
+ - **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.
20
+ - **Inspect anytime:** `synap lens` → the project + workspace + session this session resolves to.
21
+
22
+ ### The "am I in the right place?" reflex
23
+
24
+ **Before the FIRST write of a new unit of work**, check your lens and orient if you're unsure:
25
+
26
+ 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.
28
+ 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
+
30
+ **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
+
32
+ ### Notice a missing domain — and offer it
33
+
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:
35
+
36
+ > _"This project doesn't have a Marketing workspace yet — want me to spin one up and capture the essentials?"_
37
+
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.**