@synap-core/cli 1.11.0 → 1.13.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.
- package/LICENSE +21 -0
- package/README.md +40 -198
- package/dist/build-info.json +6 -0
- package/dist/commands/agent-run.js +3 -2
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/agents.d.ts +32 -17
- package/dist/commands/agents.js +203 -237
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/app.d.ts +143 -0
- package/dist/commands/app.js +524 -0
- package/dist/commands/app.js.map +1 -0
- package/dist/commands/automate.d.ts +21 -0
- package/dist/commands/automate.js +42 -0
- package/dist/commands/automate.js.map +1 -0
- package/dist/commands/automation-schema.test.d.ts +16 -0
- package/dist/commands/automation-schema.test.js +77 -0
- package/dist/commands/automation-schema.test.js.map +1 -0
- package/dist/commands/automation.d.ts +12 -0
- package/dist/commands/automation.js +116 -66
- package/dist/commands/automation.js.map +1 -1
- package/dist/commands/box.d.ts +42 -0
- package/dist/commands/box.js +89 -0
- package/dist/commands/box.js.map +1 -0
- package/dist/commands/bridge-setup.d.ts +14 -1
- package/dist/commands/bridge-setup.js +395 -129
- package/dist/commands/bridge-setup.js.map +1 -1
- package/dist/commands/cap-connections.d.ts +4 -4
- package/dist/commands/cap-connections.js +14 -14
- package/dist/commands/cap-connections.js.map +1 -1
- package/dist/commands/capability.d.ts +3 -1
- package/dist/commands/capability.js +249 -176
- package/dist/commands/capability.js.map +1 -1
- package/dist/commands/catalog.d.ts +275 -0
- package/dist/commands/catalog.js +481 -0
- package/dist/commands/catalog.js.map +1 -0
- package/dist/commands/cell.d.ts +155 -8
- package/dist/commands/cell.js +416 -40
- package/dist/commands/cell.js.map +1 -1
- package/dist/commands/centrality.js +1 -13
- package/dist/commands/centrality.js.map +1 -1
- package/dist/commands/close-questions.d.ts +27 -0
- package/dist/commands/close-questions.js +49 -0
- package/dist/commands/close-questions.js.map +1 -0
- package/dist/commands/close-questions.test.d.ts +1 -0
- package/dist/commands/close-questions.test.js +52 -0
- package/dist/commands/close-questions.test.js.map +1 -0
- package/dist/commands/connect.d.ts +36 -13
- package/dist/commands/connect.js +68 -167
- package/dist/commands/connect.js.map +1 -1
- package/dist/commands/connections.d.ts +3 -2
- package/dist/commands/connections.js +95 -25
- package/dist/commands/connections.js.map +1 -1
- package/dist/commands/context.js +79 -44
- package/dist/commands/context.js.map +1 -1
- package/dist/commands/data-extra.d.ts +34 -0
- package/dist/commands/data-extra.js +203 -25
- package/dist/commands/data-extra.js.map +1 -1
- package/dist/commands/data.d.ts +120 -2
- package/dist/commands/data.js +295 -21
- package/dist/commands/data.js.map +1 -1
- package/dist/commands/diagnose.d.ts +66 -4
- package/dist/commands/diagnose.js +285 -28
- package/dist/commands/diagnose.js.map +1 -1
- package/dist/commands/doc.d.ts +11 -4
- package/dist/commands/doc.js +39 -14
- package/dist/commands/doc.js.map +1 -1
- package/dist/commands/doctor.d.ts +133 -3
- package/dist/commands/doctor.js +761 -41
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/explain.js +5 -5
- package/dist/commands/explain.js.map +1 -1
- package/dist/commands/hooks.d.ts +19 -0
- package/dist/commands/hooks.js +70 -0
- package/dist/commands/hooks.js.map +1 -0
- package/dist/commands/import.d.ts +393 -13
- package/dist/commands/import.js +1150 -54
- package/dist/commands/import.js.map +1 -1
- package/dist/commands/init.d.ts +34 -9
- package/dist/commands/init.js +481 -981
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/keys.d.ts +1 -0
- package/dist/commands/keys.js +15 -2
- package/dist/commands/keys.js.map +1 -1
- package/dist/commands/knowledge.d.ts +22 -6
- package/dist/commands/knowledge.js +121 -57
- package/dist/commands/knowledge.js.map +1 -1
- package/dist/commands/lens.d.ts +37 -1
- package/dist/commands/lens.js +194 -72
- package/dist/commands/lens.js.map +1 -1
- package/dist/commands/market-authoring.d.ts +29 -2
- package/dist/commands/market-authoring.js +348 -7
- package/dist/commands/market-authoring.js.map +1 -1
- package/dist/commands/market-official.d.ts +58 -0
- package/dist/commands/market-official.js +84 -0
- package/dist/commands/market-official.js.map +1 -0
- package/dist/commands/market.d.ts +400 -16
- package/dist/commands/market.js +1802 -146
- package/dist/commands/market.js.map +1 -1
- package/dist/commands/mcp.d.ts +60 -25
- package/dist/commands/mcp.js +251 -64
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/observe.category.test.d.ts +1 -0
- package/dist/commands/observe.category.test.js +59 -0
- package/dist/commands/observe.category.test.js.map +1 -0
- package/dist/commands/observe.d.ts +3 -0
- package/dist/commands/observe.js +7 -5
- package/dist/commands/observe.js.map +1 -1
- package/dist/commands/observe.title.test.d.ts +1 -0
- package/dist/commands/observe.title.test.js +37 -0
- package/dist/commands/observe.title.test.js.map +1 -0
- package/dist/commands/open.d.ts +39 -9
- package/dist/commands/open.js +80 -25
- package/dist/commands/open.js.map +1 -1
- package/dist/commands/playbook.d.ts +42 -0
- package/dist/commands/playbook.js +171 -0
- package/dist/commands/playbook.js.map +1 -0
- package/dist/commands/pod.js +1 -1
- package/dist/commands/pod.js.map +1 -1
- package/dist/commands/pods.d.ts +11 -1
- package/dist/commands/pods.js +129 -131
- package/dist/commands/pods.js.map +1 -1
- package/dist/commands/proposals-actions.d.ts +62 -0
- package/dist/commands/proposals-actions.js +143 -8
- package/dist/commands/proposals-actions.js.map +1 -1
- package/dist/commands/proposals-await.d.ts +68 -0
- package/dist/commands/proposals-await.js +248 -0
- package/dist/commands/proposals-await.js.map +1 -0
- package/dist/commands/proton-setup.d.ts +73 -0
- package/dist/commands/proton-setup.js +579 -0
- package/dist/commands/proton-setup.js.map +1 -0
- package/dist/commands/providers.d.ts +23 -0
- package/dist/commands/providers.js +126 -1
- package/dist/commands/providers.js.map +1 -1
- package/dist/commands/raycast.js +6 -2
- package/dist/commands/raycast.js.map +1 -1
- package/dist/commands/rule.d.ts +150 -0
- package/dist/commands/rule.js +447 -0
- package/dist/commands/rule.js.map +1 -0
- package/dist/commands/session-feed-wait.d.ts +48 -0
- package/dist/commands/session-feed-wait.js +261 -0
- package/dist/commands/session-feed-wait.js.map +1 -0
- package/dist/commands/session-post.d.ts +40 -0
- package/dist/commands/session-post.js +96 -0
- package/dist/commands/session-post.js.map +1 -0
- package/dist/commands/session-wait.d.ts +116 -0
- package/dist/commands/session-wait.js +224 -0
- package/dist/commands/session-wait.js.map +1 -0
- package/dist/commands/sessions.d.ts +54 -0
- package/dist/commands/sessions.js +501 -58
- package/dist/commands/sessions.js.map +1 -1
- package/dist/commands/skill-manage.d.ts +21 -0
- package/dist/commands/skill-manage.js +136 -19
- package/dist/commands/skill-manage.js.map +1 -1
- package/dist/commands/skills-commands.d.ts +2 -0
- package/dist/commands/skills-commands.js +9 -1
- package/dist/commands/skills-commands.js.map +1 -1
- package/dist/commands/skills-commands.test.d.ts +1 -0
- package/dist/commands/skills-commands.test.js +57 -0
- package/dist/commands/skills-commands.test.js.map +1 -0
- package/dist/commands/skills.js +16 -0
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/status.d.ts +1 -4
- package/dist/commands/status.js +6 -35
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/statusline.backoff.test.d.ts +13 -0
- package/dist/commands/statusline.backoff.test.js +100 -0
- package/dist/commands/statusline.backoff.test.js.map +1 -0
- package/dist/commands/statusline.js +16 -9
- package/dist/commands/statusline.js.map +1 -1
- package/dist/commands/sync-status.d.ts +12 -0
- package/dist/commands/sync-status.js +125 -0
- package/dist/commands/sync-status.js.map +1 -0
- package/dist/commands/templates-retire.d.ts +34 -0
- package/dist/commands/templates-retire.js +192 -0
- package/dist/commands/templates-retire.js.map +1 -0
- package/dist/commands/tools.js +6 -21
- package/dist/commands/tools.js.map +1 -1
- package/dist/commands/tracks.d.ts +112 -0
- package/dist/commands/tracks.js +543 -0
- package/dist/commands/tracks.js.map +1 -0
- package/dist/commands/update.d.ts +3 -11
- package/dist/commands/update.js +5 -134
- package/dist/commands/update.js.map +1 -1
- package/dist/commands/upload.d.ts +41 -3
- package/dist/commands/upload.js +120 -18
- package/dist/commands/upload.js.map +1 -1
- package/dist/commands/vendor.d.ts +28 -0
- package/dist/commands/vendor.js +110 -0
- package/dist/commands/vendor.js.map +1 -0
- package/dist/commands/versions.js +6 -0
- package/dist/commands/versions.js.map +1 -1
- package/dist/commands/view.js +10 -5
- package/dist/commands/view.js.map +1 -1
- package/dist/commands/whoami.d.ts +30 -3
- package/dist/commands/whoami.js +186 -23
- package/dist/commands/whoami.js.map +1 -1
- package/dist/commands/worker-accounts.d.ts +149 -0
- package/dist/commands/worker-accounts.js +339 -0
- package/dist/commands/worker-accounts.js.map +1 -0
- package/dist/commands/worker-accounts.test.d.ts +1 -0
- package/dist/commands/worker-accounts.test.js +224 -0
- package/dist/commands/worker-accounts.test.js.map +1 -0
- package/dist/commands/worker.d.ts +331 -0
- package/dist/commands/worker.js +1067 -0
- package/dist/commands/worker.js.map +1 -0
- package/dist/commands/worker.test.d.ts +1 -0
- package/dist/commands/worker.test.js +427 -0
- package/dist/commands/worker.test.js.map +1 -0
- package/dist/commands/workspace-ops.d.ts +35 -0
- package/dist/commands/workspace-ops.js +153 -0
- package/dist/commands/workspace-ops.js.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.js +1043 -186
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-connections.d.ts +31 -0
- package/dist/lib/agent-connections.js +33 -0
- package/dist/lib/agent-connections.js.map +1 -0
- package/dist/lib/agent-detect.d.ts +27 -0
- package/dist/lib/agent-detect.js +71 -0
- package/dist/lib/agent-detect.js.map +1 -0
- package/dist/lib/agent-door.d.ts +136 -0
- package/dist/lib/agent-door.js +429 -0
- package/dist/lib/agent-door.js.map +1 -0
- package/dist/lib/agents-config.d.ts +2 -0
- package/dist/lib/agents-config.js +4 -9
- package/dist/lib/agents-config.js.map +1 -1
- package/dist/lib/approval-poll.d.ts +31 -2
- package/dist/lib/approval-poll.js +20 -7
- package/dist/lib/approval-poll.js.map +1 -1
- package/dist/lib/atomic-file.d.ts +48 -0
- package/dist/lib/atomic-file.js +129 -0
- package/dist/lib/atomic-file.js.map +1 -0
- package/dist/lib/auth.d.ts +17 -11
- package/dist/lib/auth.js +47 -64
- package/dist/lib/auth.js.map +1 -1
- package/dist/lib/batch-approval.d.ts +85 -0
- package/dist/lib/batch-approval.js +170 -0
- package/dist/lib/batch-approval.js.map +1 -0
- package/dist/lib/box/egress.d.ts +82 -0
- package/dist/lib/box/egress.js +264 -0
- package/dist/lib/box/egress.js.map +1 -0
- package/dist/lib/box/evidence.d.ts +86 -0
- package/dist/lib/box/evidence.js +121 -0
- package/dist/lib/box/evidence.js.map +1 -0
- package/dist/lib/box/job-server.d.ts +72 -0
- package/dist/lib/box/job-server.js +246 -0
- package/dist/lib/box/job-server.js.map +1 -0
- package/dist/lib/box/provisioner.d.ts +83 -0
- package/dist/lib/box/provisioner.js +312 -0
- package/dist/lib/box/provisioner.js.map +1 -0
- package/dist/lib/box/proxmox.d.ts +112 -0
- package/dist/lib/box/proxmox.js +211 -0
- package/dist/lib/box/proxmox.js.map +1 -0
- package/dist/lib/box/wire.d.ts +98 -0
- package/dist/lib/box/wire.js +70 -0
- package/dist/lib/box/wire.js.map +1 -0
- package/dist/lib/capture-lane.d.ts +6 -5
- package/dist/lib/capture-lane.js +6 -5
- package/dist/lib/capture-lane.js.map +1 -1
- package/dist/lib/capture-structure.d.ts +230 -11
- package/dist/lib/capture-structure.js +251 -13
- package/dist/lib/capture-structure.js.map +1 -1
- package/dist/lib/catalog-templates.d.ts +59 -0
- package/dist/lib/catalog-templates.js +126 -0
- package/dist/lib/catalog-templates.js.map +1 -0
- package/dist/lib/cli-build.d.ts +19 -0
- package/dist/lib/cli-build.js +37 -0
- package/dist/lib/cli-build.js.map +1 -0
- package/dist/lib/client-header.test.d.ts +1 -0
- package/dist/lib/client-header.test.js +85 -0
- package/dist/lib/client-header.test.js.map +1 -0
- package/dist/lib/conversation-headers.d.ts +33 -0
- package/dist/lib/conversation-headers.js +69 -0
- package/dist/lib/conversation-headers.js.map +1 -0
- package/dist/lib/cp-packages.d.ts +167 -11
- package/dist/lib/cp-packages.js +253 -21
- package/dist/lib/cp-packages.js.map +1 -1
- package/dist/lib/credential-class.d.ts +144 -0
- package/dist/lib/credential-class.js +138 -0
- package/dist/lib/credential-class.js.map +1 -0
- package/dist/lib/describe-lens.d.ts +35 -0
- package/dist/lib/describe-lens.js +40 -0
- package/dist/lib/describe-lens.js.map +1 -1
- package/dist/lib/device-connect.d.ts +125 -0
- package/dist/lib/device-connect.js +256 -0
- package/dist/lib/device-connect.js.map +1 -0
- package/dist/lib/directory-lens.d.ts +99 -0
- package/dist/lib/directory-lens.js +187 -0
- package/dist/lib/directory-lens.js.map +1 -0
- package/dist/lib/exporter-coverage.d.ts +71 -0
- package/dist/lib/exporter-coverage.js +97 -0
- package/dist/lib/exporter-coverage.js.map +1 -0
- package/dist/lib/goal-words.d.ts +38 -0
- package/dist/lib/goal-words.js +112 -0
- package/dist/lib/goal-words.js.map +1 -0
- package/dist/lib/hub-client.d.ts +57 -15
- package/dist/lib/hub-client.js +396 -82
- package/dist/lib/hub-client.js.map +1 -1
- package/dist/lib/init-connect.d.ts +41 -0
- package/dist/lib/init-connect.js +75 -0
- package/dist/lib/init-connect.js.map +1 -0
- package/dist/lib/init-exit.d.ts +24 -0
- package/dist/lib/init-exit.js +41 -0
- package/dist/lib/init-exit.js.map +1 -0
- package/dist/lib/init-flow.d.ts +25 -0
- package/dist/lib/init-flow.js +40 -0
- package/dist/lib/init-flow.js.map +1 -0
- package/dist/lib/init-handoff.d.ts +24 -0
- package/dist/lib/init-handoff.js +26 -0
- package/dist/lib/init-handoff.js.map +1 -0
- package/dist/lib/init-output.d.ts +18 -0
- package/dist/lib/init-output.js +43 -0
- package/dist/lib/init-output.js.map +1 -0
- package/dist/lib/init-pod.d.ts +45 -0
- package/dist/lib/init-pod.js +36 -0
- package/dist/lib/init-pod.js.map +1 -0
- package/dist/lib/installed.d.ts +210 -11
- package/dist/lib/installed.js +234 -36
- package/dist/lib/installed.js.map +1 -1
- package/dist/lib/key-approval.d.ts +57 -0
- package/dist/lib/key-approval.js +117 -0
- package/dist/lib/key-approval.js.map +1 -0
- package/dist/lib/key-diagnosis.d.ts +56 -0
- package/dist/lib/key-diagnosis.js +227 -0
- package/dist/lib/key-diagnosis.js.map +1 -0
- package/dist/lib/key-doctor.d.ts +136 -0
- package/dist/lib/key-doctor.js +286 -0
- package/dist/lib/key-doctor.js.map +1 -0
- package/dist/lib/key-locations.d.ts +120 -0
- package/dist/lib/key-locations.js +326 -0
- package/dist/lib/key-locations.js.map +1 -0
- package/dist/lib/key-source.d.ts +68 -0
- package/dist/lib/key-source.js +109 -0
- package/dist/lib/key-source.js.map +1 -0
- package/dist/lib/key-state.d.ts +70 -0
- package/dist/lib/key-state.js +115 -0
- package/dist/lib/key-state.js.map +1 -0
- package/dist/lib/kind-package.d.ts +181 -0
- package/dist/lib/kind-package.js +679 -0
- package/dist/lib/kind-package.js.map +1 -0
- package/dist/lib/knowledge-title.d.ts +25 -0
- package/dist/lib/knowledge-title.js +47 -0
- package/dist/lib/knowledge-title.js.map +1 -0
- package/dist/lib/knowledge-title.test.d.ts +1 -0
- package/dist/lib/knowledge-title.test.js +34 -0
- package/dist/lib/knowledge-title.test.js.map +1 -0
- package/dist/lib/machine-instance.d.ts +64 -0
- package/dist/lib/machine-instance.js +142 -0
- package/dist/lib/machine-instance.js.map +1 -0
- package/dist/lib/mcp-bridge.d.ts +49 -0
- package/dist/lib/mcp-bridge.js +180 -0
- package/dist/lib/mcp-bridge.js.map +1 -0
- package/dist/lib/mcp-bridge.test.d.ts +1 -0
- package/dist/lib/mcp-bridge.test.js +118 -0
- package/dist/lib/mcp-bridge.test.js.map +1 -0
- package/dist/lib/mcp-call.d.ts +30 -0
- package/dist/lib/mcp-call.js +107 -0
- package/dist/lib/mcp-call.js.map +1 -0
- package/dist/lib/mcp-snippets.d.ts +53 -0
- package/dist/lib/mcp-snippets.js +82 -0
- package/dist/lib/mcp-snippets.js.map +1 -0
- package/dist/lib/next-steps.d.ts +8 -0
- package/dist/lib/next-steps.js +31 -1
- package/dist/lib/next-steps.js.map +1 -1
- package/dist/lib/openclaw.js +3 -2
- package/dist/lib/openclaw.js.map +1 -1
- package/dist/lib/package-wire.d.ts +179 -0
- package/dist/lib/package-wire.js +68 -0
- package/dist/lib/package-wire.js.map +1 -0
- package/dist/lib/pair-link.d.ts +38 -0
- package/dist/lib/pair-link.js +68 -0
- package/dist/lib/pair-link.js.map +1 -0
- package/dist/lib/pod-moved.d.ts +70 -0
- package/dist/lib/pod-moved.js +146 -0
- package/dist/lib/pod-moved.js.map +1 -0
- package/dist/lib/pod-reach.d.ts +39 -0
- package/dist/lib/pod-reach.js +117 -0
- package/dist/lib/pod-reach.js.map +1 -0
- package/dist/lib/pod-reach.test.d.ts +1 -0
- package/dist/lib/pod-reach.test.js +67 -0
- package/dist/lib/pod-reach.test.js.map +1 -0
- package/dist/lib/pod-wide.d.ts +40 -0
- package/dist/lib/pod-wide.js +46 -0
- package/dist/lib/pod-wide.js.map +1 -0
- package/dist/lib/pod.d.ts +74 -112
- package/dist/lib/pod.js +146 -415
- package/dist/lib/pod.js.map +1 -1
- package/dist/lib/project-ref.d.ts +9 -3
- package/dist/lib/project-ref.js +10 -4
- package/dist/lib/project-ref.js.map +1 -1
- package/dist/lib/register-claude-code-mcp.test.d.ts +1 -0
- package/dist/lib/register-claude-code-mcp.test.js +78 -0
- package/dist/lib/register-claude-code-mcp.test.js.map +1 -0
- package/dist/lib/review-credential.d.ts +119 -0
- package/dist/lib/review-credential.js +149 -0
- package/dist/lib/review-credential.js.map +1 -0
- package/dist/lib/safe-open.d.ts +49 -0
- package/dist/lib/safe-open.js +119 -0
- package/dist/lib/safe-open.js.map +1 -0
- package/dist/lib/session-feed.d.ts +185 -0
- package/dist/lib/session-feed.js +257 -0
- package/dist/lib/session-feed.js.map +1 -0
- package/dist/lib/session-lens.d.ts +40 -1
- package/dist/lib/session-lens.js +54 -4
- package/dist/lib/session-lens.js.map +1 -1
- package/dist/lib/superwhisper-import.d.ts +8 -0
- package/dist/lib/superwhisper-import.js +14 -7
- package/dist/lib/superwhisper-import.js.map +1 -1
- package/dist/lib/superwhisper-title.test.d.ts +1 -0
- package/dist/lib/superwhisper-title.test.js +18 -0
- package/dist/lib/superwhisper-title.test.js.map +1 -0
- package/dist/lib/targets.d.ts +152 -10
- package/dist/lib/targets.js +974 -325
- package/dist/lib/targets.js.map +1 -1
- package/dist/lib/template-file.d.ts +4 -0
- package/dist/lib/template-file.js.map +1 -1
- package/dist/lib/template-lifecycle.d.ts +217 -0
- package/dist/lib/template-lifecycle.js +433 -0
- package/dist/lib/template-lifecycle.js.map +1 -0
- package/dist/lib/template-steps.d.ts +88 -0
- package/dist/lib/template-steps.js +118 -0
- package/dist/lib/template-steps.js.map +1 -0
- package/dist/lib/time-ago.d.ts +2 -0
- package/dist/lib/time-ago.js +15 -0
- package/dist/lib/time-ago.js.map +1 -0
- package/dist/lib/wake-hook-settings.d.ts +57 -0
- package/dist/lib/wake-hook-settings.js +153 -0
- package/dist/lib/wake-hook-settings.js.map +1 -0
- package/dist/lib/wake-state.d.ts +65 -0
- package/dist/lib/wake-state.js +122 -0
- package/dist/lib/wake-state.js.map +1 -0
- package/dist/utils/logger.js +5 -2
- package/dist/utils/logger.js.map +1 -1
- package/package.json +26 -17
- package/skills/README.md +13 -11
- package/skills/agent-os/SKILL.md +214 -99
- package/skills/manifest.json +1 -1
- package/skills/onboard/SKILL.md +55 -26
- package/skills/synap/README.md +5 -8
- package/skills/synap/SKILL.md +1149 -289
- package/skills/synap/_order.txt +7 -0
- package/skills/synap/_skill.yaml +1 -1
- package/skills/synap/automations.md +15 -0
- package/skills/synap/capture.md +5 -0
- package/skills/synap/cli-operations.md +24 -18
- package/skills/synap/code-skills.md +70 -0
- package/skills/synap/concepts.md +36 -0
- package/skills/synap/content-os.md +10 -1
- package/skills/synap/creative-loop.md +15 -10
- package/skills/synap/crm.md +21 -52
- package/skills/synap/document-embeds.md +143 -47
- package/skills/synap/escalation-ladder.md +20 -10
- package/skills/synap/focus-sessions.md +56 -21
- package/skills/synap/from-intent.md +158 -0
- package/skills/synap/governance-rules.md +5 -5
- package/skills/synap/governance.md +10 -7
- package/skills/synap/hand-off.md +33 -0
- package/skills/synap/inline-patterns.md +15 -7
- package/skills/synap/lenses.md +34 -16
- package/skills/synap/linking.md +42 -41
- package/skills/synap/mcp-remote-servers.md +64 -0
- package/skills/synap/mental-model.md +17 -15
- package/skills/synap/operating-mode-rules.md +2 -2
- package/skills/synap/processes.md +118 -0
- package/skills/synap/quick-reference.md +7 -2
- package/skills/synap/reading.md +3 -1
- package/skills/synap/reflexes.md +12 -42
- package/skills/synap/viewframe-cells.md +38 -5
- package/skills/synap/work-flow.md +1 -1
- package/skills/synap/work-model.md +110 -0
- package/skills/synap/worked-examples.md +4 -5
- package/skills/synap/workspace-design.md +15 -11
- package/skills/synap/writes.md +105 -25
- package/skills/synap/writing-titles.md +63 -0
- package/skills/synap-app/SKILL.md +149 -67
- package/skills/synap-app/_skill.yaml +1 -1
- package/skills/synap-app/creating-the-base-app.md +12 -7
- package/skills/synap-app/governance.md +27 -16
- package/skills/synap-app/install-commands.md +18 -9
- package/skills/synap-app/overview.md +16 -9
- package/skills/synap-app/using-the-sdk.md +75 -25
- package/skills/synap-design/SKILL.md +474 -0
- package/skills/synap-design/_order.txt +4 -0
- package/skills/synap-design/_skill.yaml +21 -0
- package/skills/synap-design/loop.md +134 -0
- package/skills/synap-design/overview.md +44 -0
- package/skills/synap-design/principles.md +130 -0
- package/skills/synap-design/system.md +133 -0
- package/skills/synap-market/SKILL.md +306 -16
- package/skills/synap-market/_skill.yaml +1 -1
- package/skills/synap-market/author-and-publish.md +145 -8
- package/skills/synap-market/governance-and-catalog.md +7 -0
- package/skills/synap-market/install.md +79 -1
- package/skills/synap-market/overview.md +74 -6
- package/skills/synap-schema/SKILL.md +172 -10
- package/skills/synap-schema/_order.txt +2 -0
- package/skills/synap-schema/_skill.yaml +4 -2
- package/skills/synap-schema/common-mistakes.md +4 -2
- package/skills/synap-schema/discover-profiles.md +1 -1
- package/skills/synap-schema/entity-scope.md +15 -3
- package/skills/synap-schema/extend-first.md +29 -0
- package/skills/synap-schema/extend-vs-create.md +1 -1
- package/skills/synap-schema/intent-vocabulary-ssot.md +111 -0
- package/skills/synap-schema/property-types.md +1 -1
- package/skills/synap-schema/relations.md +1 -1
- package/skills/synap-ui/SKILL.md +19 -12
- package/skills/synap-ui/_skill.yaml +1 -1
- package/skills/synap-ui/ai-companion.md +1 -1
- package/skills/synap-ui/arranging-bento.md +2 -0
- package/skills/synap-ui/bento-layouts.md +10 -10
- package/skills/synap-ui/bento-recipes.md +313 -543
- package/skills/synap-ui/four-builds.md +5 -0
- package/skills/synap-ui/view-types.md +2 -2
- package/skills/synap-ui/widget-catalog.md +22 -278
- package/templates/automations/bookmark-enrichment.automation.json +290 -13
- package/templates/automations/url-bookmark-capture.automation.json +73 -11
- package/templates/box/runner.py +206 -0
- package/templates/skills/authoring-playbooks/SKILL.md +6 -3
- package/templates/skills/authoring-playbooks/reference/stages-contract.md +15 -0
- package/templates/skills/authoring-playbooks/reference/worked-example.md +3 -0
- package/dist/commands/infra.d.ts +0 -21
- package/dist/commands/infra.js +0 -262
- package/dist/commands/infra.js.map +0 -1
- package/node_modules/@synap/hub-rest-client/dist/index.cjs +0 -1261
- package/node_modules/@synap/hub-rest-client/dist/index.d.cts +0 -1647
- package/node_modules/@synap/hub-rest-client/dist/index.d.ts +0 -1647
- package/node_modules/@synap/hub-rest-client/dist/index.js +0 -1231
- package/node_modules/@synap/hub-rest-client/package.json +0 -45
- package/node_modules/@synap/hub-rest-client/src/client.ts +0 -1631
- package/node_modules/@synap/hub-rest-client/src/errors.ts +0 -30
- package/node_modules/@synap/hub-rest-client/src/index.ts +0 -153
- package/node_modules/@synap/hub-rest-client/src/setup.ts +0 -133
- package/node_modules/@synap/hub-rest-client/src/types.ts +0 -1299
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
synap market install crm # install as a new workspace
|
|
7
7
|
synap market install crm --dry-run # preview: would-create / reuse / conflicts, writes nothing
|
|
8
8
|
synap market install crm --onto <workspaceId> # reconcile ONTO an existing workspace (additive)
|
|
9
|
-
synap market install crm --project <id> #
|
|
9
|
+
synap market install crm --project <id> # link the installed workspace(s) to an EXISTING project (id only)
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
Installs are **workspace-first**: a `workspace`/`template` package spins up
|
|
@@ -14,6 +14,8 @@ Installs are **workspace-first**: a `workspace`/`template` package spins up
|
|
|
14
14
|
automation, cell) route you to the right surface (`synap capability add`,
|
|
15
15
|
etc.) rather than being force-fit into a workspace install.
|
|
16
16
|
|
|
17
|
+
**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. Reinstalling reuses the live space. A template is installed **once per pod**, and a space name is held by **one** active space — whoever owns it, human or agent alike: a second copy is refused (`409` — `status: "exists"` + the space to use, or `WORKSPACE_IDENTITY_CONFLICT` naming the space that holds it). There are no named copies: `--as <name>` / `instanceName` answers `400`, and a package with no `_meta.slug` (and no `--onto` target) answers `400` instead of minting a second space.
|
|
18
|
+
|
|
17
19
|
## Pod verb — `market.install` (MCP / agent / automation)
|
|
18
20
|
|
|
19
21
|
```json
|
|
@@ -37,6 +39,59 @@ never treat a non-"installed" response as failure:
|
|
|
37
39
|
they can approve it — don't retry, don't report it as a failure. See
|
|
38
40
|
`governance-and-catalog.md`.
|
|
39
41
|
|
|
42
|
+
## Project packs — a suite of workspaces, linked to a project
|
|
43
|
+
|
|
44
|
+
A **project** is a cross-cutting lens over workspaces, not a package kind. A
|
|
45
|
+
"project pack" is a **suite**: an ordinary `workspace`-category package tagged
|
|
46
|
+
`suite`, whose `dependencies[]` **`require`** each constituent workspace package
|
|
47
|
+
(never `compose` — re-applying must not duplicate workspaces). Installing a
|
|
48
|
+
suite installs every constituent workspace (idempotent: reused if present).
|
|
49
|
+
|
|
50
|
+
**Author one from a live project** — never hand-write the suite:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
synap market publish --from-project <projectId> # publishes the constituents first, then the thin suite
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
(Agent door: `export_project_pack` returns `{ definition, constituents }` —
|
|
57
|
+
publish the constituents before the suite so every `require` resolves.)
|
|
58
|
+
|
|
59
|
+
**Install onto a project.** The install never needs to know why the project
|
|
60
|
+
exists — it installs the workspaces and LINKS them (a `project --uses-->
|
|
61
|
+
workspace` edge per workspace, plus seeded entities filed into the project):
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
synap market install <suite-slug> --project <projectId> # EXISTING project id only; errors if not found
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The CLI has no flag that creates a project. Create the project first:
|
|
68
|
+
|
|
69
|
+
- **A human**: in the app, or by passing `projectName` on the Hub door
|
|
70
|
+
`POST /api/hub/packages/apply` (mints or reuses by exact name).
|
|
71
|
+
- **An agent**: `create_project` requires `evidenceEntityIds` — at least 5
|
|
72
|
+
existing entities that belong to it — or it is REJECTED (not proposed).
|
|
73
|
+
Without that evidence, ask the human to create the project, then install with
|
|
74
|
+
its id.
|
|
75
|
+
- **An agent calling `market.install` with `projectName`**: the install becomes
|
|
76
|
+
a proposal that carries the name, and when a human approves it the project is
|
|
77
|
+
minted. The approval is the consent — say so when you propose it.
|
|
78
|
+
|
|
79
|
+
Two packs on one project = install each with the same `--project <id>`. Each
|
|
80
|
+
lands its own workspaces; both link to the project. Only ONE `compose`
|
|
81
|
+
dependency is allowed per package, at every level.
|
|
82
|
+
|
|
83
|
+
**The brief comes with the workspaces.** A workspace package's `onboarding` is
|
|
84
|
+
the space's BRIEF — steady state (`purpose`, `framing`, `expertise`, `anchors`,
|
|
85
|
+
`fetch`) plus its onboarding mode (`goal`, `collect`, `openingQuestions`,
|
|
86
|
+
`doneWhen`) — stored on that workspace's `settings.onboarding`; the package's
|
|
87
|
+
top-level `rules[]` install as the space's rules. A template update reaches an
|
|
88
|
+
installed space without overwriting what its owner edited (conflicts are
|
|
89
|
+
reported), and `synap_update_space_brief` proposes a change. The `onboard` skill runs the
|
|
90
|
+
interview when a lens is empty; for a project spanning several workspaces it
|
|
91
|
+
sets up one workspace's slice at a time, each entity filed into the project.
|
|
92
|
+
There is no project-level recipe — the recipe always lives on a workspace. A
|
|
93
|
+
journey completes by itself once the lens holds real data.
|
|
94
|
+
|
|
40
95
|
## Idempotency by kind
|
|
41
96
|
|
|
42
97
|
- **capability** — natural key is `(name, workspaceId)`; installing twice
|
|
@@ -47,6 +102,29 @@ they can approve it — don't retry, don't report it as a failure. See
|
|
|
47
102
|
- **automation** — pre-checked by `(name, workspace)` before creating.
|
|
48
103
|
- **cell** — keyed by `(typeKey, workspaceId)`.
|
|
49
104
|
|
|
105
|
+
## Template updates — where a space stands, and whose step it is
|
|
106
|
+
|
|
107
|
+
Read it with MCP `synap_template_health` (or `synap templates` in a terminal).
|
|
108
|
+
Each space's row says what is left to do; act on these fields, not on
|
|
109
|
+
`drifted` alone (`drifted: true` means "there is a step", not "apply now"):
|
|
110
|
+
|
|
111
|
+
| Field | Means | Your move |
|
|
112
|
+
|---|---|---|
|
|
113
|
+
| `state: "active"`, `drifted: true` | a newer version is out | the update path below |
|
|
114
|
+
| `state: "awaiting-approval"` + `awaitingApproval: [ids]` | the last update filed proposals | point the person to them; **do not re-apply** |
|
|
115
|
+
| `state: "partial"` / `"layer-2-not-run"` / `"failed"` | the last update did not finish | `synap templates update <slug>` finishes it |
|
|
116
|
+
| `pendingDataChanges: {count, sentences, needsPodAdmin}` | the update changes existing data and waits for a **person** to agree | tell them the sentences; they run `synap templates update <slug>` themselves (a pod owner/admin when `needsPodAdmin`) |
|
|
117
|
+
| `updateProposal: {id}` | an update of this space is already proposed | point the person to that proposal; **never file another** |
|
|
118
|
+
| `applyWarning` | the pod's one sentence for what is left | relay it as is |
|
|
119
|
+
|
|
120
|
+
The update path is `synap templates update <slug>` (the person's door). Run
|
|
121
|
+
with an agent key it becomes a proposal the person approves. **Agreeing to data
|
|
122
|
+
changes is never an agent's**: the door answers `409
|
|
123
|
+
DATA_CHANGES_NEED_CONSENT` with `needsPerson: true` for any agent, whatever it
|
|
124
|
+
lists in `acceptDataChanges`. The version stamp (`settings.template.version`) is
|
|
125
|
+
written only when an update converged, so a space never reads "up to date" over
|
|
126
|
+
an update that did not land.
|
|
127
|
+
|
|
50
128
|
## Locked / tier-gated packages
|
|
51
129
|
|
|
52
130
|
A package can declare a `requiredTier`. Installing one your account's plan
|
|
@@ -1,10 +1,78 @@
|
|
|
1
1
|
# Marketplace & templates on Synap
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
Synap is **configuration-first**: a feature is _stored, user-editable config_
|
|
4
|
+
published to one catalog and installed through shared substrate — not hardcoded in
|
|
5
|
+
the pod backend. The marketplace is that **package layer**, and the catalog
|
|
6
|
+
(`synap_packages`) is **kind-agnostic** — one door serves every kind:
|
|
7
|
+
|
|
8
|
+
| Kind | Configures | Standalone install (via `applyMarketInstall`) |
|
|
9
|
+
| ------------------------- | ---------------------------------------------------------------- | -------------------------------------------------- |
|
|
10
|
+
| **workspace** | a whole domain (profiles + views + bento + its caps/automations) | ✅ `createWorkspaceFromDefinitionIdempotent` |
|
|
11
|
+
| **capability** | a credentialed tool pack (+ embedded skills/playbooks) | ✅ `createCapabilityFromDefinition` |
|
|
12
|
+
| **cell** | a renderer — the code that draws an entity/widget | ✅ `installCellFromDefinition` (needs a cache row) |
|
|
13
|
+
| **view** | a saved view/layout | ✅ `viewsRouter.create` (needs a `workspaceId`) |
|
|
14
|
+
| **skill** | agent know-how | ✅ `skillsRouter.create` (pod-wide if no ws) |
|
|
15
|
+
| **workflow / automation** | a WHEN→ACTION flow | ✅ `automationsRouter.create` into acting ws |
|
|
16
|
+
|
|
17
|
+
**All six kinds install standalone today** through the ONE apply core
|
|
18
|
+
`applyMarketInstall` (`services/capabilities/marketplace-install.ts`) — the same
|
|
19
|
+
governed door `market.install` and the `capability.install` proposal executor share,
|
|
20
|
+
each reusing the kind's _governed_ router caller (zero duplicated insert logic). The
|
|
21
|
+
remaining gaps are NOT install: (1) **private-package sync is unauthenticated**, so a
|
|
22
|
+
private package can't reach a pod yet (see `governance-and-catalog.md` / RC4); (2)
|
|
23
|
+
standalone **view / skill / automation stamp no source-link**, so they don't self-heal
|
|
24
|
+
via reconcile the way workspace/capability do. (Subscription-`tier` gating is a
|
|
25
|
+
separate axis — see `governance-and-catalog.md`.)
|
|
26
|
+
|
|
27
|
+
**Words** (template, pack, workspace/work/track/rule template) are defined once
|
|
28
|
+
in the `synap` skill's `concepts` topic. In short: a template's kind is DERIVED
|
|
29
|
+
from its content (a playbook with `scope: "project"` is a track template, the
|
|
30
|
+
default `scope: "session"` a work template), never declared.
|
|
31
|
+
|
|
32
|
+
**A pack is not a seventh kind.** Today it ships as a **suite**: a `workspace`
|
|
33
|
+
package tagged `suite` that `require`s its constituent workspaces, built from a
|
|
34
|
+
live project with `synap market publish --from-project <id>`, and installed
|
|
35
|
+
with `--project <id>` to link every workspace to that project. See
|
|
36
|
+
`install.md` → "Project packs". The model it is moving to: a pack lists the
|
|
37
|
+
workspace templates it depends on and installs the missing ones, and never
|
|
38
|
+
creates a workspace of its own.
|
|
39
|
+
|
|
40
|
+
It lives in the Control Plane (CP) catalog and is discoverable and installable from
|
|
41
|
+
any door: the `synap` CLI, MCP (`market_search` / `run_capability`), or the Hub REST
|
|
42
|
+
API. **Everything that is config, not code, can be a template** — workspaces, entity
|
|
43
|
+
profiles/views, renderers (cells), capabilities, skills, automations.
|
|
44
|
+
|
|
45
|
+
## The authoring order — bottom-up, ALWAYS
|
|
46
|
+
|
|
47
|
+
Everything installable is a **standalone package**, and packages form a graph: a
|
|
48
|
+
bigger one **declares `dependencies[]`** on smaller ones, and the pod installs the
|
|
49
|
+
missing ones in the same governed pass. So author from the SMALLEST piece up:
|
|
50
|
+
|
|
51
|
+
1. **Basic objects** — entity types (profiles), **skills**, capabilities, cells,
|
|
52
|
+
views, workflow/automations. Each is publishable on its OWN and is useful before
|
|
53
|
+
any container exists. A skill package is one skill: its documentation or code.
|
|
54
|
+
2. **Containers** — a **space** (a `workspace` template) that declares
|
|
55
|
+
`dependencies[]` on the basic objects it needs, and activates its skills with a
|
|
56
|
+
`skills:` block.
|
|
57
|
+
3. **Compositions** — a **project / suite** ("truck") that `require`s the spaces.
|
|
58
|
+
|
|
59
|
+
Publish the small pieces FIRST, then the space, then install. Nothing in the chain
|
|
60
|
+
waits on a container.
|
|
61
|
+
|
|
62
|
+
**The two verbs are different, and confusing them is the classic mistake:**
|
|
63
|
+
|
|
64
|
+
- `dependencies[]` = what gets **INSTALLED** — the pod materialises the package if
|
|
65
|
+
it is not already there (idempotent; a second pass reports `found`).
|
|
66
|
+
- `skills:` inside a template = what gets **LINKED** to that space, and in which
|
|
67
|
+
mode (`always` / `on-demand`). It names a skill some `dependencies[]` entry —
|
|
68
|
+
usually its own — already installed. Declaring the link without the dependency
|
|
69
|
+
installs cleanly and links NOTHING.
|
|
70
|
+
|
|
71
|
+
**Never inline what is already a package.** Copying a skill's text into a template,
|
|
72
|
+
or re-declaring a profile set that ships as a dependency, forks the thing and stops
|
|
73
|
+
it converging. Depend on it; let the install bring it. And **never** seed a skill
|
|
74
|
+
into the backend (`skills/synap/…`) to make a template resolve — that directory is
|
|
75
|
+
not the marketplace. Publish it as a package.
|
|
8
76
|
|
|
9
77
|
## The two reflexes
|
|
10
78
|
|
|
@@ -40,7 +108,7 @@ REST API (`/api/hub/capabilities/execute`).
|
|
|
40
108
|
The CLI's browse filter (`market --type`) uses
|
|
41
109
|
`workspace|capability|skill|workflow|view|cell`; the pod-native install verb
|
|
42
110
|
(`market.install`) and its catalog use the narrower
|
|
43
|
-
`capability|automation|template|cell` (workspace
|
|
111
|
+
`capability|automation|template|cell` (`template` there means a workspace template). Match
|
|
44
112
|
whichever surface you're calling.
|
|
45
113
|
|
|
46
114
|
## Visibility
|
|
@@ -9,11 +9,13 @@ description: >
|
|
|
9
9
|
schema", defining custom relations, setting up a profile for a specific domain
|
|
10
10
|
(real estate, music production, research, fitness, cooking). Also triggers on:
|
|
11
11
|
"do I already have a profile for X?", "what fields does <profile> have?",
|
|
12
|
-
extending an existing profile with workspace-specific overlay properties
|
|
12
|
+
extending an existing profile with workspace-specific overlay properties,
|
|
13
|
+
widening a role so a hat fits another kind (any kind, not only person/company).
|
|
14
|
+
Prefer extend-first (system/synap-schema/extend-first) before define_kind.
|
|
13
15
|
Do NOT use this skill for creating instances of existing types — the core
|
|
14
16
|
`synap` skill handles that. This skill changes the SCHEMA, not the data.
|
|
15
17
|
metadata:
|
|
16
|
-
|
|
18
|
+
synap:
|
|
17
19
|
requires:
|
|
18
20
|
env: [SYNAP_HUB_API_KEY, SYNAP_POD_URL]
|
|
19
21
|
primaryEnv: SYNAP_HUB_API_KEY
|
|
@@ -117,7 +119,7 @@ Read the response:
|
|
|
117
119
|
|
|
118
120
|
### Commonly seeded profiles (verify before using)
|
|
119
121
|
|
|
120
|
-
Standard pods typically include: `note`, `task`, `
|
|
122
|
+
Standard pods typically include: `note`, `task`, `event`, `person`, `contact`, `company`, `item`, `bookmark`, `website`, `article`, `capture`, `file`, `anchor`, `decision`, `question`, `research`. A **project is not a profile** — it is a row in `projects`. Roles (vendor, client, …) appear as `profileKind: role`.
|
|
121
123
|
|
|
122
124
|
CRM workspaces additionally have: `deal`, `client` — but **only** when a CRM workspace was created.
|
|
123
125
|
Custom workspace templates (devplane, content, etc.) add their own profiles entirely.
|
|
@@ -130,7 +132,7 @@ Before creating a new profile: **does one of these already fit?** A podcast epis
|
|
|
130
132
|
|
|
131
133
|
There are three moves, not two. Before extending or creating, ask whether the thing is really a **role** the entity plays rather than a new kind of entity at all — that's a facet, and it's the move people skip.
|
|
132
134
|
|
|
133
|
-
**Kind + Facets, the rule:** one entity = one kind (`profiles.profileKind = 'kind'`). Roles
|
|
135
|
+
**Kind + Facets, the rule:** one entity = one kind (`profiles.profileKind = 'kind'`). Roles are hats on **any** kind — not only person/company. A role-profile (`profileKind = 'role'`, `applicableKinds[]`) attaches via `entity_facets`: additive, workspace-lensed, NOT a second entity. `applicableKinds` NULL = any kind; a list **restricts**. “This item is an X” is a facet on `item` when X is a hat, not a new kind. Only promote a role to a full kind if it accrues its own independent life. Widen a role (`define_role` on the existing slug) when the hat fits a kind that is not yet in `applicableKinds`. See `extend-first.md`.
|
|
134
136
|
|
|
135
137
|
**The litmus test:**
|
|
136
138
|
|
|
@@ -160,6 +162,38 @@ Prefer **inheritance** over new profiles when a system parent fits. `contact ext
|
|
|
160
162
|
|
|
161
163
|
---
|
|
162
164
|
|
|
165
|
+
## Extend first — schema moves, in order
|
|
166
|
+
|
|
167
|
+
Before `define_kind` or a new workspace, walk this list **top to bottom**. Stop at the first move that fits. Load from `system/synap-schema/extend-first`. The conductor for a fuzzy user intent is `system/synap/from-intent`.
|
|
168
|
+
|
|
169
|
+
A **role (facet) is a hat on any entity kind**, not only person/company. `applicableKinds` is the allowlist (`NULL` = any kind). `kind_mismatch` means **widen the role**, not mint a sibling type.
|
|
170
|
+
|
|
171
|
+
| # | If the need is… | Do this | Do not |
|
|
172
|
+
| --- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
173
|
+
| 1 | An instance of a kind you already have | `create_entity` / capture on that slug; search first | A second kind with a similar name |
|
|
174
|
+
| 2 | A **hat** on an existing entity (“this item is an X”, “this company is a vendor”) | `attach_facet`. If the role exists but not on this kind → **widen `applicableKinds`** (same slug, extra kinds) then attach | A new kind or a second role slug (`seller` vs `vendor`) |
|
|
175
|
+
| 3 | 1–3 extra fields in **one** domain | Workspace **overlay** property on the existing kind | A forked kind in that workspace |
|
|
176
|
+
| 4 | A true **subtype** with its own fields and life | Child kind: `define_kind` with `parentProfileSlug` of the closest parent | A disconnected top-level kind |
|
|
177
|
+
| 5 | A **relationship-with-a-life** (buyer × seller × price × stage, independent of either party) | Own kind (the **deal precedent**). New slug if CRM `deal` is a _sales pipeline_ and this is not that. Overlay if it **is** the same kind in another workspace | Twin slug `deal`; JSON arrays of prices on the thing; Finding-per-scrape |
|
|
178
|
+
| 6 | A **stage** inside a domain | Status field + view | A workspace per stage |
|
|
179
|
+
| 7 | A **domain** (owns kinds + own team + automations + stable) | Four-test → `agent-os` / template | A workspace for a project, a hat, or a shopping list |
|
|
180
|
+
| 8 | None of the above | `define_kind` (pod-wide default) | Silent invent |
|
|
181
|
+
|
|
182
|
+
Same **kind** across workspaces: **one profile**, overlays for extra fields, optional `entityScope: pod` (pod-admin) so instances are not trapped. Never a second profile with the same name.
|
|
183
|
+
|
|
184
|
+
### Widen a role
|
|
185
|
+
|
|
186
|
+
`synap_define_role` with an **existing** slug is slug-idempotent: extra `applicableKinds` are **merged** (widen only). Shrinking the allowlist is not this door.
|
|
187
|
+
|
|
188
|
+
### Firewalls
|
|
189
|
+
|
|
190
|
+
- `list_profiles` before every define.
|
|
191
|
+
- Prefer attach / widen / overlay / parent over create.
|
|
192
|
+
- One structural proposal at a time.
|
|
193
|
+
- `proposed` is success.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
163
197
|
## Creating a new profile
|
|
164
198
|
|
|
165
199
|
```json
|
|
@@ -241,10 +275,22 @@ Overlays don't leak: workspace A can't see workspace B's overlay properties even
|
|
|
241
275
|
|
|
242
276
|
Profiles have an `entityScope` that determines where entities of that type live:
|
|
243
277
|
|
|
244
|
-
- `entityScope: "pod"` — entities are pod-wide
|
|
245
|
-
- `entityScope: "workspace"` — entities live in the workspace they were created in. Good for deals,
|
|
278
|
+
- `entityScope: "pod"` — entities are **pod-wide** (home `workspace_id = NULL`). Visible under ACL + role-as-lens facets — **not** exclusive to one app. Good for people, companies, notes, articles, knowledge/lessons — identity and memory that cross contexts.
|
|
279
|
+
- `entityScope: "workspace"` — entities live in the workspace they were created in (process kinds). Good for deals, pipelines, workspace-specific artifacts.
|
|
280
|
+
|
|
281
|
+
**Default is `pod`** (schema column default + write door). Only declare `entityScope: "workspace"` when the kind is a genuine process document that must not float pod-wide.
|
|
282
|
+
|
|
283
|
+
### Pin ≠ exclusive prison
|
|
246
284
|
|
|
247
|
-
|
|
285
|
+
Filing into a workspace sets a **home pin**, not exclusive ownership. Role facets make the same person visible in CRM (or Operations) without copying the row. Never treat workspace pin as a folder that traps identity.
|
|
286
|
+
|
|
287
|
+
### Write pins (agents & capture)
|
|
288
|
+
|
|
289
|
+
- **Omit** `workspaceId` for pod-scope kinds — server placement lands them pod-wide.
|
|
290
|
+
- **Ambient / active workspace** is a **list lens** and optional process home, not a silent dump target.
|
|
291
|
+
- Process kinds + explicit pin / routed domain home use `resolveKindWritePin` (one rule for capture, import, thought).
|
|
292
|
+
|
|
293
|
+
If you're creating a profile for something clearly pod-wide (a person, a podcast, a book, a lesson), leave default pod or set `entityScope: "pod"` explicitly. Do **not** set workspace "to be safe" — that reintroduces folder-trap bugs.
|
|
248
294
|
|
|
249
295
|
---
|
|
250
296
|
|
|
@@ -265,7 +311,121 @@ POST /api/hub/relation-defs
|
|
|
265
311
|
}
|
|
266
312
|
```
|
|
267
313
|
|
|
268
|
-
Defining a relation def is rarely worth it — `
|
|
314
|
+
Defining a relation def is rarely worth it — `relates_to` + a property usually suffices. Only create one when the relationship is semantic enough that UI should treat it specially (e.g., show "mentored by Jane" on a person's profile card).
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## The intent vocabulary — one SSOT, two mirrors
|
|
319
|
+
|
|
320
|
+
**What a capability DOES** — `send_message`, `generate_media`, `publish_post`,
|
|
321
|
+
`delegate_agent_task` — is the
|
|
322
|
+
ROUTING axis over the verb catalog. A verb's id is vendor-keyed (`gmail_send`,
|
|
323
|
+
`unipile_send_message`); its `intent` says what it MEANS, so an agent can ask for
|
|
324
|
+
"send a message" without already knowing the vendor.
|
|
325
|
+
|
|
326
|
+
An intent is **routing only, never authorization**. It resolves to a concrete verb id
|
|
327
|
+
BEFORE the governance gate, which then decides on the verb exactly as it did before.
|
|
328
|
+
|
|
329
|
+
### THE SOURCE OF TRUTH IS A TABLE, NOT A UNION
|
|
330
|
+
|
|
331
|
+
The SSOT is the pod's **`capability_intents` table**. Slugs live in ROWS, not in a
|
|
332
|
+
TypeScript union:
|
|
333
|
+
|
|
334
|
+
```sql
|
|
335
|
+
SELECT slug, effect, statement FROM capability_intents ORDER BY slug;
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
| Column | Meaning |
|
|
339
|
+
| ----------- | --------------------------------------------------------- |
|
|
340
|
+
| `slug` | the seat. `^[a-z][a-z0-9_]{0,63}$` (a CHECK constraint) |
|
|
341
|
+
| `effect` | CLOSED axis a rule may key on: `read` \| `write` \| `act` |
|
|
342
|
+
| `statement` | the human sentence |
|
|
343
|
+
| `synonyms` | for FINDING a row, never for identity |
|
|
344
|
+
|
|
345
|
+
This is why every code-side copy is a **mirror** and not the source. A slug that fits
|
|
346
|
+
none of the existing rows leaves `intent` UNSET; the vocabulary is deliberately not
|
|
347
|
+
open for developers to mint (cf. W3C Web Intents, abandoned partly for that reason).
|
|
348
|
+
|
|
349
|
+
### The two mirrors, and why each one must exist
|
|
350
|
+
|
|
351
|
+
There are exactly **two**. Two more were removed: `AbstractVerb` in
|
|
352
|
+
`@synap/playbooks` (deleted 2026-10-01, see below), and the pod's own
|
|
353
|
+
`ABSTRACT_VERBS` copy (collapsed 2026-10-26 — `@synap/database` now depends on
|
|
354
|
+
`@synap-core/types`, so it re-exports mirror 1 under that name).
|
|
355
|
+
|
|
356
|
+
| # | Where | Kind | Why it cannot import the SSOT |
|
|
357
|
+
| --- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
358
|
+
| 1 | `synap-backend/packages/types/src/capability-intents/` — `ABSTRACT_INTENTS`, `REGISTERED_EXTRAS`, `CAPABILITY_INTENTS` | runtime, published leaf | The SSOT is SQL rows; a TypeScript list is a mirror by construction. The pod reads it too: `ABSTRACT_VERBS` in `packages/database/src/schema/tools.ts` is this `ABSTRACT_INTENTS`, re-exported (the 0283 SEED union, 13). |
|
|
359
|
+
| 2 | `synap-control-plane-api/src/seeds/capability-intent-vocabulary.ts` — `ABSTRACT_VERBS`, `REGISTERED_EXTRAS`, `CAPABILITY_INTENTS` | runtime, the CP catalog seeder | The control plane is a **separate deploy target with its own `pnpm-lock.yaml`**. It resolves neither `@synap-core/types` nor the pod's packages (verified: `require.resolve('@synap-core/types')` → `MODULE_NOT_FOUND`). |
|
|
360
|
+
|
|
361
|
+
Consumed by: `@synap/api` (`intent-registry`, `create-from-definition`,
|
|
362
|
+
`schemas/playbook-definition.ts`), `synap-app/packages/workspace-templates`
|
|
363
|
+
(`validate.ts` — the `taskIntents` check), and the CP's `seed-capability-templates.ts`
|
|
364
|
+
(only the insert-only bootstrap of an empty CP — official capabilities are authored in
|
|
365
|
+
the catalog, `synap-app/packages/workspace-templates/capabilities/`, and published with
|
|
366
|
+
`synap catalog publish --official`).
|
|
367
|
+
|
|
368
|
+
### Which field on which surface
|
|
369
|
+
|
|
370
|
+
Search for this chapter by the field you are holding, not by the word "intent":
|
|
371
|
+
|
|
372
|
+
| Field | Lives on | Means |
|
|
373
|
+
| ----------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------- |
|
|
374
|
+
| `intent` | a **skill** in a capability definition; a `ToolVerb` catalog entry | what ONE verb does |
|
|
375
|
+
| `provides` | a **capability template** | every intent the whole PACK serves — must equal the `intent` its skills declare |
|
|
376
|
+
| `taskIntents` | a **workspace template** | what the SPACE needs the pod to be able to do |
|
|
377
|
+
| `requiredIntents` | a **playbook** | what the PROCESS needs the pod to be able to do |
|
|
378
|
+
|
|
379
|
+
All four are validated against this ONE vocabulary, so a workspace and a playbook
|
|
380
|
+
cannot be spelled from two different lists.
|
|
381
|
+
|
|
382
|
+
### THE PLAYBOOKS MIRROR WAS DELETED — do not re-add it
|
|
383
|
+
|
|
384
|
+
`AbstractVerb` in `@synap/playbooks/src/index.ts` was a TYPE-only mirror of all 13
|
|
385
|
+
slugs. It was **stale** (no `publish_post`) and **dead** — a whole-repo scan across
|
|
386
|
+
every repo, `src/`, `dist/`, and generated `.d.ts` found **zero importers**.
|
|
387
|
+
|
|
388
|
+
A mirror nothing imports and nothing checks is not a mirror: it is a comment that
|
|
389
|
+
looks like a contract. `packages/playbooks/src/required-intents.test.ts` now refuses
|
|
390
|
+
`AbstractVerb`, `ABSTRACT_INTENTS`, or `REGISTERED_EXTRAS` being re-declared there.
|
|
391
|
+
|
|
392
|
+
`ToolVerb.intent` is `string`, not a closed union, and must stay that way: a union in
|
|
393
|
+
a package that consumes nothing would go stale in the one direction that is invisible.
|
|
394
|
+
|
|
395
|
+
### Adding a slug — the exact steps
|
|
396
|
+
|
|
397
|
+
1. **Write the migration.** A new numbered `.sql` in `synap-backend/packages/database/migrations/`,
|
|
398
|
+
`INSERT INTO "capability_intents" ("slug", "effect", "statement") VALUES (...) ON CONFLICT ("slug") DO NOTHING;`
|
|
399
|
+
`effect` ∈ `read|write|act`. Never `drizzle-kit generate` — hand-write it, and mirror it into
|
|
400
|
+
`0000_baseline_schema.sql` if it adds a table or column.
|
|
401
|
+
2. **Add it to mirror 1** — `ABSTRACT_INTENTS` (a SEED slug) or `REGISTERED_EXTRAS`
|
|
402
|
+
(a post-seed row) in `packages/types/src/capability-intents/index.ts`. The pod's
|
|
403
|
+
`ABSTRACT_VERBS` is `ABSTRACT_INTENTS`, so it follows. Then **`cd packages/types && pnpm build`** —
|
|
404
|
+
consumers typecheck against the built `dist/`, so a skipped rebuild makes your gate lie.
|
|
405
|
+
Post-seed rows today: `publish_post` (0284, write), `delegate_agent_task`
|
|
406
|
+
(0314, act — every verb of an external-agent binding, `tools.config.agentBinding`:
|
|
407
|
+
start / send / status / cancel) and `read_webpage` (0329).
|
|
408
|
+
3. **Add it to mirror 2** — the same two lists in the control plane's
|
|
409
|
+
`capability-intent-vocabulary.ts`.
|
|
410
|
+
4. **Update the arity floors** — `SEED_SLUG_ARITY` / `EXTRA_SLUG_ARITY` in
|
|
411
|
+
`packages/api/src/__tripwires__/intent-vocabulary-one-ssot.tripwire.test.ts`.
|
|
412
|
+
These are the ONE place you must edit by hand, and the build stops until you do.
|
|
413
|
+
|
|
414
|
+
A slug in the table but missing from a mirror is **not silent**: every guard re-derives
|
|
415
|
+
from the migration SQL, so it is a red build — never a divergence nobody notices.
|
|
416
|
+
|
|
417
|
+
### What can still go wrong
|
|
418
|
+
|
|
419
|
+
- **A mirror can be added.** Nothing structurally prevents a third copy; the tripwire
|
|
420
|
+
only polices the names it knows. This is why step 4 exists as a hand-edit floor.
|
|
421
|
+
- **A guard proves SAMENESS, never CORRECTNESS.** If every mirror and the migration agree
|
|
422
|
+
on a slug that should not exist, all four guards stay green. The vocabulary's MEANING is
|
|
423
|
+
reviewed by a human, not derived.
|
|
424
|
+
- **A new migration file is not auto-scanned.** Each parity guard lists its migration
|
|
425
|
+
filenames. A slug added in `0295_…sql` is invisible to all of them until that list is
|
|
426
|
+
extended — so extending it is part of step 1, not a follow-up.
|
|
427
|
+
- **`@synap-core/types` is published.** Mirror 2 ships to npm; changing it without a
|
|
428
|
+
version bump leaves consumers on the old vocabulary.
|
|
269
429
|
|
|
270
430
|
---
|
|
271
431
|
|
|
@@ -308,9 +468,11 @@ Defining a relation def is rarely worth it — `related_to` + a property usually
|
|
|
308
468
|
2. **Declaring properties inline on the profile object.** Properties are separate rows; use `POST /property-defs`.
|
|
309
469
|
3. **Using `string` for what should be `entity_id`.** If the field refers to another entity (host of a podcast), use `entity_id` + `targetProfileSlug` — enables auto-sync and link UX.
|
|
310
470
|
4. **Using `array` of strings for tags.** Tags are a built-in concept; reuse the `tags` property on `note`/`project` instead of creating a parallel field.
|
|
311
|
-
5. **
|
|
471
|
+
5. **Wrong `entityScope`.** Defaults to **`pod`**. Only set `entityScope: "workspace"` for process kinds (deals, pipelines). Do not pin people/knowledge to a workspace "to be safe."
|
|
312
472
|
6. **Creating an overlay when a base property is wanted.** Overlays only appear in one workspace. If the user wants the field everywhere, don't set `overlay: true`.
|
|
313
|
-
7. **Creating a custom profile when extension would work.**
|
|
473
|
+
7. **Creating a custom profile when extension would work.** Child kind (`parentProfileSlug`) or a **facet on any kind** is cleaner than a twin slug.
|
|
474
|
+
8. **Treating facets as person/company-only.** A hat can sit on `item`, `task`, `deal`, …. `kind_mismatch` → widen `applicableKinds`, don't mint `seller` next to `vendor`.
|
|
475
|
+
9. **Twin `deal` slug for a price timeline.** CRM `deal` is a sales pipeline. A commercial snapshot with its own life is the deal _precedent_ (own kind) or overlays on the same kind — never a second profile named deal.
|
|
314
476
|
|
|
315
477
|
---
|
|
316
478
|
|
|
@@ -3,11 +3,13 @@ before-you-touch.md
|
|
|
3
3
|
read-before-write.md
|
|
4
4
|
discover-profiles.md
|
|
5
5
|
extend-vs-create.md
|
|
6
|
+
extend-first.md
|
|
6
7
|
creating-profiles.md
|
|
7
8
|
property-defs.md
|
|
8
9
|
overlay-properties.md
|
|
9
10
|
entity-scope.md
|
|
10
11
|
relations.md
|
|
12
|
+
intent-vocabulary-ssot.md
|
|
11
13
|
worked-example.md
|
|
12
14
|
common-mistakes.md
|
|
13
15
|
more.md
|
|
@@ -8,11 +8,13 @@ description: >
|
|
|
8
8
|
schema", defining custom relations, setting up a profile for a specific domain
|
|
9
9
|
(real estate, music production, research, fitness, cooking). Also triggers on:
|
|
10
10
|
"do I already have a profile for X?", "what fields does <profile> have?",
|
|
11
|
-
extending an existing profile with workspace-specific overlay properties
|
|
11
|
+
extending an existing profile with workspace-specific overlay properties,
|
|
12
|
+
widening a role so a hat fits another kind (any kind, not only person/company).
|
|
13
|
+
Prefer extend-first (system/synap-schema/extend-first) before define_kind.
|
|
12
14
|
Do NOT use this skill for creating instances of existing types — the core
|
|
13
15
|
`synap` skill handles that. This skill changes the SCHEMA, not the data.
|
|
14
16
|
metadata:
|
|
15
|
-
|
|
17
|
+
synap:
|
|
16
18
|
requires:
|
|
17
19
|
env: [SYNAP_HUB_API_KEY, SYNAP_POD_URL]
|
|
18
20
|
primaryEnv: SYNAP_HUB_API_KEY
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
2. **Declaring properties inline on the profile object.** Properties are separate rows; use `POST /property-defs`.
|
|
5
5
|
3. **Using `string` for what should be `entity_id`.** If the field refers to another entity (host of a podcast), use `entity_id` + `targetProfileSlug` — enables auto-sync and link UX.
|
|
6
6
|
4. **Using `array` of strings for tags.** Tags are a built-in concept; reuse the `tags` property on `note`/`project` instead of creating a parallel field.
|
|
7
|
-
5. **
|
|
7
|
+
5. **Wrong `entityScope`.** Defaults to **`pod`**. Only set `entityScope: "workspace"` for process kinds (deals, pipelines). Do not pin people/knowledge to a workspace "to be safe."
|
|
8
8
|
6. **Creating an overlay when a base property is wanted.** Overlays only appear in one workspace. If the user wants the field everywhere, don't set `overlay: true`.
|
|
9
|
-
7. **Creating a custom profile when extension would work.**
|
|
9
|
+
7. **Creating a custom profile when extension would work.** Child kind (`parentProfileSlug`) or a **facet on any kind** is cleaner than a twin slug.
|
|
10
|
+
8. **Treating facets as person/company-only.** A hat can sit on `item`, `task`, `deal`, …. `kind_mismatch` → widen `applicableKinds`, don't mint `seller` next to `vendor`.
|
|
11
|
+
9. **Twin `deal` slug for a price timeline.** CRM `deal` is a sales pipeline. A commercial snapshot with its own life is the deal _precedent_ (own kind) or overlays on the same kind — never a second profile named deal.
|
|
@@ -16,7 +16,7 @@ Read the response:
|
|
|
16
16
|
|
|
17
17
|
### Commonly seeded profiles (verify before using)
|
|
18
18
|
|
|
19
|
-
Standard pods typically include: `note`, `task`, `
|
|
19
|
+
Standard pods typically include: `note`, `task`, `event`, `person`, `contact`, `company`, `item`, `bookmark`, `website`, `article`, `capture`, `file`, `anchor`, `decision`, `question`, `research`. A **project is not a profile** — it is a row in `projects`. Roles (vendor, client, …) appear as `profileKind: role`.
|
|
20
20
|
|
|
21
21
|
CRM workspaces additionally have: `deal`, `client` — but **only** when a CRM workspace was created.
|
|
22
22
|
Custom workspace templates (devplane, content, etc.) add their own profiles entirely.
|
|
@@ -2,7 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
Profiles have an `entityScope` that determines where entities of that type live:
|
|
4
4
|
|
|
5
|
-
- `entityScope: "pod"` — entities are pod-wide
|
|
6
|
-
- `entityScope: "workspace"` — entities live in the workspace they were created in. Good for deals,
|
|
5
|
+
- `entityScope: "pod"` — entities are **pod-wide** (home `workspace_id = NULL`). Visible under ACL + role-as-lens facets — **not** exclusive to one app. Good for people, companies, notes, articles, knowledge/lessons — identity and memory that cross contexts.
|
|
6
|
+
- `entityScope: "workspace"` — entities live in the workspace they were created in (process kinds). Good for deals, pipelines, workspace-specific artifacts.
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
**Default is `pod`** (schema column default + write door). Only declare `entityScope: "workspace"` when the kind is a genuine process document that must not float pod-wide.
|
|
9
|
+
|
|
10
|
+
### Pin ≠ exclusive prison
|
|
11
|
+
|
|
12
|
+
Filing into a workspace sets a **home pin**, not exclusive ownership. Role facets make the same person visible in CRM (or Operations) without copying the row. Never treat workspace pin as a folder that traps identity.
|
|
13
|
+
|
|
14
|
+
### Write pins (agents & capture)
|
|
15
|
+
|
|
16
|
+
- **Omit** `workspaceId` for pod-scope kinds — server placement lands them pod-wide.
|
|
17
|
+
- **Ambient / active workspace** is a **list lens** and optional process home, not a silent dump target.
|
|
18
|
+
- Process kinds + explicit pin / routed domain home use `resolveKindWritePin` (one rule for capture, import, thought).
|
|
19
|
+
|
|
20
|
+
If you're creating a profile for something clearly pod-wide (a person, a podcast, a book, a lesson), leave default pod or set `entityScope: "pod"` explicitly. Do **not** set workspace "to be safe" — that reintroduces folder-trap bugs.
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
## Extend first — schema moves, in order
|
|
2
|
+
|
|
3
|
+
Before `define_kind` or a new workspace, walk this list **top to bottom**. Stop at the first move that fits. Load from `system/synap-schema/extend-first`. The conductor for a fuzzy user intent is `system/synap/from-intent`.
|
|
4
|
+
|
|
5
|
+
A **role (facet) is a hat on any entity kind**, not only person/company. `applicableKinds` is the allowlist (`NULL` = any kind). `kind_mismatch` means **widen the role**, not mint a sibling type.
|
|
6
|
+
|
|
7
|
+
| # | If the need is… | Do this | Do not |
|
|
8
|
+
| --- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
9
|
+
| 1 | An instance of a kind you already have | `create_entity` / capture on that slug; search first | A second kind with a similar name |
|
|
10
|
+
| 2 | A **hat** on an existing entity (“this item is an X”, “this company is a vendor”) | `attach_facet`. If the role exists but not on this kind → **widen `applicableKinds`** (same slug, extra kinds) then attach | A new kind or a second role slug (`seller` vs `vendor`) |
|
|
11
|
+
| 3 | 1–3 extra fields in **one** domain | Workspace **overlay** property on the existing kind | A forked kind in that workspace |
|
|
12
|
+
| 4 | A true **subtype** with its own fields and life | Child kind: `define_kind` with `parentProfileSlug` of the closest parent | A disconnected top-level kind |
|
|
13
|
+
| 5 | A **relationship-with-a-life** (buyer × seller × price × stage, independent of either party) | Own kind (the **deal precedent**). New slug if CRM `deal` is a _sales pipeline_ and this is not that. Overlay if it **is** the same kind in another workspace | Twin slug `deal`; JSON arrays of prices on the thing; Finding-per-scrape |
|
|
14
|
+
| 6 | A **stage** inside a domain | Status field + view | A workspace per stage |
|
|
15
|
+
| 7 | A **domain** (owns kinds + own team + automations + stable) | Four-test → `agent-os` / template | A workspace for a project, a hat, or a shopping list |
|
|
16
|
+
| 8 | None of the above | `define_kind` (pod-wide default) | Silent invent |
|
|
17
|
+
|
|
18
|
+
Same **kind** across workspaces: **one profile**, overlays for extra fields, optional `entityScope: pod` (pod-admin) so instances are not trapped. Never a second profile with the same name.
|
|
19
|
+
|
|
20
|
+
### Widen a role
|
|
21
|
+
|
|
22
|
+
`synap_define_role` with an **existing** slug is slug-idempotent: extra `applicableKinds` are **merged** (widen only). Shrinking the allowlist is not this door.
|
|
23
|
+
|
|
24
|
+
### Firewalls
|
|
25
|
+
|
|
26
|
+
- `list_profiles` before every define.
|
|
27
|
+
- Prefer attach / widen / overlay / parent over create.
|
|
28
|
+
- One structural proposal at a time.
|
|
29
|
+
- `proposed` is success.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
There are three moves, not two. Before extending or creating, ask whether the thing is really a **role** the entity plays rather than a new kind of entity at all — that's a facet, and it's the move people skip.
|
|
4
4
|
|
|
5
|
-
**Kind + Facets, the rule:** one entity = one kind (`profiles.profileKind = 'kind'`). Roles
|
|
5
|
+
**Kind + Facets, the rule:** one entity = one kind (`profiles.profileKind = 'kind'`). Roles are hats on **any** kind — not only person/company. A role-profile (`profileKind = 'role'`, `applicableKinds[]`) attaches via `entity_facets`: additive, workspace-lensed, NOT a second entity. `applicableKinds` NULL = any kind; a list **restricts**. “This item is an X” is a facet on `item` when X is a hat, not a new kind. Only promote a role to a full kind if it accrues its own independent life. Widen a role (`define_role` on the existing slug) when the hat fits a kind that is not yet in `applicableKinds`. See `extend-first.md`.
|
|
6
6
|
|
|
7
7
|
**The litmus test:**
|
|
8
8
|
|