@synap-core/workspace-templates 0.7.2 → 0.7.4

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 (44) hide show
  1. package/dist/index.d.ts +207 -8
  2. package/dist/index.js +2122 -1427
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/src/agent-fleet.yaml +666 -108
  6. package/src/blockchain-ecosystem.yaml +1 -0
  7. package/src/brand-library.yaml +127 -12
  8. package/src/builder.yaml +116 -12
  9. package/src/business-developer.yaml +102 -18
  10. package/src/catalog.ts +13 -3
  11. package/src/communication.yaml +23 -453
  12. package/src/composition-graph.test.ts +26 -0
  13. package/src/content-os.yaml +103 -10
  14. package/src/content-studio.yaml +1 -0
  15. package/src/crm.yaml +12 -0
  16. package/src/define.ts +8 -8
  17. package/src/dev-dashboard.yaml +43 -9
  18. package/src/domains.test.ts +117 -0
  19. package/src/domains.ts +102 -0
  20. package/src/ecosystem.yaml +21 -4
  21. package/src/enterprise-os.yaml +5 -0
  22. package/src/finance.yaml +46 -5
  23. package/src/foundation.yaml +13 -1
  24. package/src/grants.yaml +1 -0
  25. package/src/hr.yaml +61 -8
  26. package/src/index.ts +29 -0
  27. package/src/internal-runbook.yaml +36 -5
  28. package/src/legal.yaml +97 -12
  29. package/src/life-os.yaml +188 -27
  30. package/src/marketing.yaml +15 -2
  31. package/src/meetings-knowledge.yaml +7 -1
  32. package/src/operations.yaml +351 -0
  33. package/src/outreach-comms.yaml +6 -1
  34. package/src/project-management.yaml +840 -111
  35. package/src/research-base.yaml +516 -0
  36. package/src/research-decision.yaml +158 -0
  37. package/src/shared-role-ssot.test.ts +268 -0
  38. package/src/social.yaml +105 -37
  39. package/src/templates.ts +4573 -4302
  40. package/src/the-arch.yaml +11 -0
  41. package/src/types.ts +9 -0
  42. package/src/validate.test.ts +81 -0
  43. package/src/validate.ts +561 -0
  44. package/src/personal.yaml +0 -177
package/dist/index.js CHANGED
@@ -11,6 +11,7 @@ var DATA = {
11
11
  "agent-fleet": {
12
12
  "meta": {
13
13
  "slug": "agent-fleet",
14
+ "domain": "build",
14
15
  "name": "Agent Fleet",
15
16
  "description": "Manage your fleet of AI agents \u2014 the agents, their providers, skills, and the work they do.",
16
17
  "icon": "bot",
@@ -2738,6 +2739,7 @@ var DATA = {
2738
2739
  "blockchain-ecosystem": {
2739
2740
  "meta": {
2740
2741
  "slug": "blockchain-ecosystem",
2742
+ "domain": "strategy",
2741
2743
  "name": "Blockchain Ecosystem",
2742
2744
  "description": "Web3 market actors \u2014 market-makers, auditors, dev shops, KOLs \u2014 and how they connect. Overlays the Ecosystem workspace.",
2743
2745
  "icon": "boxes",
@@ -3210,6 +3212,7 @@ var DATA = {
3210
3212
  "brand-library": {
3211
3213
  "meta": {
3212
3214
  "slug": "brand-library",
3215
+ "domain": "content",
3213
3216
  "name": "Brand Library",
3214
3217
  "description": "Reusable source of truth for brand identity, colors, typography, assets, tokens, templates, and generation rules.",
3215
3218
  "icon": "palette",
@@ -4348,6 +4351,7 @@ var DATA = {
4348
4351
  "builder-workspace": {
4349
4352
  "meta": {
4350
4353
  "slug": "builder-workspace",
4354
+ "domain": "build",
4351
4355
  "name": "Builder",
4352
4356
  "description": "Builder workspace \u2014 apps, features, services, packages, environments, deployments, recipes, decisions, incidents, plus delegated agent tasks/projects/skills/providers.",
4353
4357
  "icon": "wrench",
@@ -6761,6 +6765,7 @@ var DATA = {
6761
6765
  "business-developer": {
6762
6766
  "meta": {
6763
6767
  "slug": "business-developer",
6768
+ "domain": "revenue",
6764
6769
  "name": "Business Developer",
6765
6770
  "description": "A lead-first sales motion for a CRM workspace: qualify leads, work commercial proposals, and hand won clients to the next system.",
6766
6771
  "icon": "target",
@@ -7793,6 +7798,7 @@ var DATA = {
7793
7798
  "communication": {
7794
7799
  "meta": {
7795
7800
  "slug": "communication",
7801
+ "domain": "content",
7796
7802
  "name": "Communication",
7797
7803
  "description": "Owns brand identity, voice, and narrative/positioning \u2014 the on-brand source of truth every downstream domain (Content, Marketing, Social) reads from so everything ships on-brand and on-message.",
7798
7804
  "icon": "messages-square",
@@ -7806,931 +7812,132 @@ var DATA = {
7806
7812
  ],
7807
7813
  "isPublic": true
7808
7814
  },
7815
+ "dependencies": [
7816
+ {
7817
+ "slug": "brand-library",
7818
+ "kind": "workspace",
7819
+ "relation": "compose",
7820
+ "reason": "Layers positioning, narrative, and audience onto your Brand Library."
7821
+ }
7822
+ ],
7809
7823
  "workspace": {
7810
- "name": "Communication",
7811
- "description": "Owns brand identity, voice, and narrative/positioning \u2014 the on-brand source of truth every downstream domain reads from.",
7812
- "subtype": "communication",
7813
- "visibility": "pod_visible",
7824
+ "name": "Brand Library",
7825
+ "description": "The strategic messaging layer \u2014 positioning, narrative, audience, and differentiators \u2014 layered onto your Brand Library.",
7826
+ "subtype": "brand-library",
7814
7827
  "capabilities": [
7815
- "brand.library",
7816
- "brand.identity",
7817
7828
  "brand.voice",
7818
- "brand.assets",
7819
- "brand.templates",
7820
- "brand.components",
7821
7829
  "narrative.positioning"
7822
7830
  ],
7823
7831
  "sourceRoles": {
7824
- "brand": "consumer",
7825
7832
  "narrative": "provider"
7826
7833
  }
7827
7834
  },
7828
7835
  "profiles": [
7829
7836
  {
7830
- "slug": "brand-identity",
7831
- "displayName": "Brand Identity",
7832
- "icon": "fingerprint",
7833
- "color": "amber",
7834
- "description": "Root brand context: positioning, audience, website, voice summary, and generation intent.",
7835
- "semanticSlug": "brand.identity",
7837
+ "slug": "positioning",
7838
+ "displayName": "Positioning",
7839
+ "icon": "crosshair",
7840
+ "color": "cyan",
7841
+ "description": "Market category, who we stand against, and why we win.",
7836
7842
  "properties": [
7837
7843
  {
7838
- "slug": "brand-type",
7839
- "label": "Brand type",
7840
- "valueType": "string",
7841
- "inputType": "select",
7842
- "enumValues": [
7843
- "product-digital",
7844
- "product-physical",
7845
- "agency",
7846
- "personal-brand",
7847
- "nonprofit",
7848
- "institutional",
7849
- "universal"
7850
- ],
7851
- "constraints": {
7852
- "defaultValue": "universal"
7853
- }
7854
- },
7855
- {
7856
- "slug": "brand-status",
7857
- "label": "Status",
7858
- "valueType": "string",
7859
- "inputType": "select",
7860
- "enumValues": [
7861
- "draft",
7862
- "active",
7863
- "archived"
7864
- ],
7865
- "constraints": {
7866
- "defaultValue": "active"
7867
- }
7868
- },
7869
- {
7870
- "slug": "brand-tagline",
7871
- "label": "Tagline",
7872
- "valueType": "string",
7873
- "inputType": "text"
7874
- },
7875
- {
7876
- "slug": "brand-website",
7877
- "label": "Website",
7878
- "valueType": "string",
7879
- "inputType": "url"
7880
- },
7881
- {
7882
- "slug": "brand-industry",
7883
- "label": "Industry",
7844
+ "slug": "category",
7845
+ "label": "Category",
7884
7846
  "valueType": "string",
7885
7847
  "inputType": "text"
7886
7848
  },
7887
7849
  {
7888
- "slug": "brand-positioning",
7889
- "label": "Positioning",
7890
- "valueType": "string",
7891
- "inputType": "textarea"
7892
- },
7893
- {
7894
- "slug": "brand-audience-primary",
7895
- "label": "Primary audience",
7896
- "valueType": "string",
7897
- "inputType": "textarea"
7898
- },
7899
- {
7900
- "slug": "brand-audience-secondary",
7901
- "label": "Secondary audience",
7902
- "valueType": "string",
7903
- "inputType": "textarea"
7904
- },
7905
- {
7906
- "slug": "brand-voice-summary",
7907
- "label": "Voice summary",
7850
+ "slug": "against",
7851
+ "label": "Against",
7908
7852
  "valueType": "string",
7909
7853
  "inputType": "textarea"
7910
7854
  },
7911
7855
  {
7912
- "slug": "brand-notes",
7913
- "label": "Notes",
7856
+ "slug": "because",
7857
+ "label": "Because",
7914
7858
  "valueType": "string",
7915
7859
  "inputType": "textarea"
7916
7860
  }
7917
7861
  ]
7918
7862
  },
7919
7863
  {
7920
- "slug": "brand-color",
7921
- "displayName": "Brand Color",
7922
- "icon": "swatch-book",
7923
- "color": "violet",
7924
- "description": "Approved palette entry with semantic role, usage notes, and print references.",
7925
- "semanticSlug": "brand.color",
7864
+ "slug": "narrative",
7865
+ "displayName": "Narrative",
7866
+ "icon": "book-open",
7867
+ "color": "amber",
7868
+ "description": "The origin -> insight -> mission story arc.",
7926
7869
  "properties": [
7927
7870
  {
7928
- "slug": "color-role",
7929
- "label": "Role",
7871
+ "slug": "arc",
7872
+ "label": "Story arc",
7930
7873
  "valueType": "string",
7931
- "inputType": "select",
7932
- "enumValues": [
7933
- "primary",
7934
- "secondary",
7935
- "accent",
7936
- "background",
7937
- "surface",
7938
- "surface-elevated",
7939
- "text",
7940
- "text-muted",
7941
- "border",
7942
- "success",
7943
- "warning",
7944
- "error",
7945
- "info",
7946
- "neutral",
7947
- "campaign",
7948
- "custom"
7949
- ],
7950
- "constraints": {
7951
- "defaultValue": "custom"
7952
- }
7874
+ "inputType": "textarea"
7953
7875
  },
7954
7876
  {
7955
- "slug": "color-group",
7956
- "label": "Group",
7877
+ "slug": "status",
7878
+ "label": "Status",
7957
7879
  "valueType": "string",
7958
7880
  "inputType": "select",
7959
7881
  "enumValues": [
7960
- "core",
7961
- "extended",
7962
- "semantic",
7963
- "neutral",
7964
- "seasonal",
7965
- "campaign"
7882
+ "draft",
7883
+ "active",
7884
+ "archived"
7966
7885
  ],
7967
7886
  "constraints": {
7968
- "defaultValue": "core"
7887
+ "defaultValue": "active"
7969
7888
  }
7970
- },
7971
- {
7972
- "slug": "color-hex",
7973
- "label": "Hex",
7974
- "valueType": "string",
7975
- "inputType": "color"
7976
- },
7977
- {
7978
- "slug": "color-rgb",
7979
- "label": "RGB",
7980
- "valueType": "string",
7981
- "inputType": "text"
7982
- },
7983
- {
7984
- "slug": "color-cmyk",
7985
- "label": "CMYK",
7986
- "valueType": "string",
7987
- "inputType": "text"
7988
- },
7989
- {
7990
- "slug": "color-pantone",
7991
- "label": "Pantone",
7992
- "valueType": "string",
7993
- "inputType": "text"
7994
- },
7889
+ }
7890
+ ]
7891
+ },
7892
+ {
7893
+ "slug": "audience",
7894
+ "displayName": "Audience",
7895
+ "icon": "users",
7896
+ "color": "blue",
7897
+ "description": "An ideal customer profile \u2014 who we are built for.",
7898
+ "properties": [
7995
7899
  {
7996
- "slug": "color-ral",
7997
- "label": "RAL",
7900
+ "slug": "segment",
7901
+ "label": "Segment",
7998
7902
  "valueType": "string",
7999
7903
  "inputType": "text"
8000
7904
  },
8001
7905
  {
8002
- "slug": "color-token-name",
8003
- "label": "Token name",
7906
+ "slug": "persona",
7907
+ "label": "Persona",
8004
7908
  "valueType": "string",
8005
- "inputType": "text"
7909
+ "inputType": "textarea"
8006
7910
  },
8007
7911
  {
8008
- "slug": "color-usage",
8009
- "label": "Usage note",
7912
+ "slug": "jobs-to-be-done",
7913
+ "label": "Jobs to be done",
8010
7914
  "valueType": "string",
8011
7915
  "inputType": "textarea"
8012
7916
  },
8013
7917
  {
8014
- "slug": "color-status",
8015
- "label": "Status",
8016
- "valueType": "string",
8017
- "inputType": "select",
8018
- "enumValues": [
8019
- "draft",
8020
- "approved",
8021
- "deprecated"
8022
- ],
8023
- "constraints": {
8024
- "defaultValue": "approved"
8025
- }
7918
+ "slug": "traits",
7919
+ "label": "Traits",
7920
+ "valueType": "array",
7921
+ "inputType": "text"
8026
7922
  }
8027
7923
  ]
8028
7924
  },
8029
7925
  {
8030
- "slug": "brand-font",
8031
- "displayName": "Brand Typeface",
8032
- "icon": "type",
8033
- "color": "blue",
8034
- "description": "Typeface with role, family, licensing, import URL, weights, and fallback stack.",
8035
- "semanticSlug": "brand.font",
7926
+ "slug": "differentiator",
7927
+ "displayName": "Differentiator",
7928
+ "icon": "sparkles",
7929
+ "color": "green",
7930
+ "description": "One thing only we do, believe, or refuse.",
8036
7931
  "properties": [
8037
7932
  {
8038
- "slug": "font-role",
8039
- "label": "Role",
7933
+ "slug": "statement",
7934
+ "label": "Statement",
8040
7935
  "valueType": "string",
8041
- "inputType": "select",
8042
- "enumValues": [
8043
- "heading",
8044
- "body",
8045
- "display",
8046
- "mono",
8047
- "accent",
8048
- "ui",
8049
- "caption"
8050
- ],
8051
- "constraints": {
8052
- "defaultValue": "body"
8053
- }
7936
+ "inputType": "textarea"
8054
7937
  },
8055
7938
  {
8056
- "slug": "font-family",
8057
- "label": "Family",
8058
- "valueType": "string",
8059
- "inputType": "text"
8060
- },
8061
- {
8062
- "slug": "font-foundry",
8063
- "label": "Foundry",
8064
- "valueType": "string",
8065
- "inputType": "text"
8066
- },
8067
- {
8068
- "slug": "font-license",
8069
- "label": "License",
8070
- "valueType": "string",
8071
- "inputType": "select",
8072
- "enumValues": [
8073
- "open-source",
8074
- "google-fonts",
8075
- "adobe-fonts",
8076
- "licensed",
8077
- "custom",
8078
- "system"
8079
- ],
8080
- "constraints": {
8081
- "defaultValue": "google-fonts"
8082
- }
8083
- },
8084
- {
8085
- "slug": "font-weights",
8086
- "label": "Weights",
8087
- "valueType": "string",
8088
- "inputType": "text"
8089
- },
8090
- {
8091
- "slug": "font-fallback",
8092
- "label": "Fallback stack",
8093
- "valueType": "string",
8094
- "inputType": "text"
8095
- },
8096
- {
8097
- "slug": "font-url",
8098
- "label": "Import URL",
8099
- "valueType": "string",
8100
- "inputType": "url"
8101
- },
8102
- {
8103
- "slug": "font-document-id",
8104
- "label": "Font document ID",
8105
- "valueType": "string",
8106
- "inputType": "text"
8107
- },
8108
- {
8109
- "slug": "font-status",
8110
- "label": "Status",
8111
- "valueType": "string",
8112
- "inputType": "select",
8113
- "enumValues": [
8114
- "active",
8115
- "draft",
8116
- "deprecated"
8117
- ],
8118
- "constraints": {
8119
- "defaultValue": "active"
8120
- }
8121
- }
8122
- ]
8123
- },
8124
- {
8125
- "slug": "brand-asset",
8126
- "displayName": "Brand Asset",
8127
- "icon": "image",
8128
- "color": "green",
8129
- "description": "Document-backed or URL-backed reusable media: logos, imagery, icons, fonts, video, references, and documents.",
8130
- "semanticSlug": "brand.asset",
8131
- "properties": [
8132
- {
8133
- "slug": "asset-kind",
8134
- "label": "Kind",
8135
- "valueType": "string",
8136
- "inputType": "select",
8137
- "enumValues": [
8138
- "logo",
8139
- "wordmark",
8140
- "symbol",
8141
- "monogram",
8142
- "pattern",
8143
- "texture",
8144
- "icon-set",
8145
- "illustration",
8146
- "photo",
8147
- "video",
8148
- "document",
8149
- "font",
8150
- "3d-model",
8151
- "print-ready",
8152
- "reference",
8153
- "other"
8154
- ]
8155
- },
8156
- {
8157
- "slug": "asset-variant",
8158
- "label": "Variant",
8159
- "valueType": "string",
8160
- "inputType": "select",
8161
- "enumValues": [
8162
- "primary",
8163
- "secondary",
8164
- "horizontal",
8165
- "stacked",
8166
- "mono-dark",
8167
- "mono-light",
8168
- "white",
8169
- "reversed",
8170
- "favicon",
8171
- "social-avatar",
8172
- "og-image",
8173
- "other"
8174
- ]
8175
- },
8176
- {
8177
- "slug": "asset-status",
8178
- "label": "Status",
8179
- "valueType": "string",
8180
- "inputType": "select",
8181
- "enumValues": [
8182
- "draft",
8183
- "approved",
8184
- "deprecated"
8185
- ],
8186
- "constraints": {
8187
- "defaultValue": "approved"
8188
- }
8189
- },
8190
- {
8191
- "slug": "asset-usage",
8192
- "label": "Usage notes",
8193
- "valueType": "string",
8194
- "inputType": "textarea"
8195
- },
8196
- {
8197
- "slug": "asset-tags",
8198
- "label": "Tags",
8199
- "valueType": "string",
8200
- "inputType": "text"
8201
- },
8202
- {
8203
- "slug": "asset-url",
8204
- "label": "External URL",
8205
- "valueType": "string",
8206
- "inputType": "url"
8207
- },
8208
- {
8209
- "slug": "asset-document-id",
8210
- "label": "Document ID",
8211
- "valueType": "string",
8212
- "inputType": "text"
8213
- },
8214
- {
8215
- "slug": "asset-file-id",
8216
- "label": "Legacy file ID",
8217
- "valueType": "string",
8218
- "inputType": "text"
8219
- },
8220
- {
8221
- "slug": "asset-alt-text",
8222
- "label": "Alt text",
8223
- "valueType": "string",
8224
- "inputType": "textarea"
8225
- }
8226
- ]
8227
- },
8228
- {
8229
- "slug": "brand-reference",
8230
- "displayName": "Brand Reference",
8231
- "icon": "bookmark",
8232
- "color": "teal",
8233
- "description": "Website, competitor, campaign, moodboard, or example used as source context for generation.",
8234
- "semanticSlug": "brand.reference",
8235
- "properties": [
8236
- {
8237
- "slug": "reference-kind",
8238
- "label": "Kind",
8239
- "valueType": "string",
8240
- "inputType": "select",
8241
- "enumValues": [
8242
- "website",
8243
- "competitor",
8244
- "campaign",
8245
- "moodboard",
8246
- "copy-example",
8247
- "design-example",
8248
- "customer-example",
8249
- "other"
8250
- ]
8251
- },
8252
- {
8253
- "slug": "reference-url",
8254
- "label": "URL",
8255
- "valueType": "string",
8256
- "inputType": "url"
8257
- },
8258
- {
8259
- "slug": "reference-notes",
8260
- "label": "Notes",
8261
- "valueType": "string",
8262
- "inputType": "textarea"
8263
- },
8264
- {
8265
- "slug": "reference-status",
8266
- "label": "Status",
8267
- "valueType": "string",
8268
- "inputType": "select",
8269
- "enumValues": [
8270
- "draft",
8271
- "approved",
8272
- "archived"
8273
- ],
8274
- "constraints": {
8275
- "defaultValue": "approved"
8276
- }
8277
- }
8278
- ]
8279
- },
8280
- {
8281
- "slug": "brand-token-set",
8282
- "displayName": "Token Set",
8283
- "icon": "code-2",
8284
- "color": "violet",
8285
- "description": "Generated or curated design tokens for color, typography, spacing, radii, and exported CSS variables.",
8286
- "semanticSlug": "brand.tokens",
8287
- "properties": [
8288
- {
8289
- "slug": "token-status",
8290
- "label": "Status",
8291
- "valueType": "string",
8292
- "inputType": "select",
8293
- "enumValues": [
8294
- "draft",
8295
- "active",
8296
- "archived"
8297
- ],
8298
- "constraints": {
8299
- "defaultValue": "active"
8300
- }
8301
- },
8302
- {
8303
- "slug": "token-mode",
8304
- "label": "Mode",
8305
- "valueType": "string",
8306
- "inputType": "select",
8307
- "enumValues": [
8308
- "base",
8309
- "light",
8310
- "dark",
8311
- "high-contrast",
8312
- "campaign",
8313
- "experimental"
8314
- ],
8315
- "constraints": {
8316
- "defaultValue": "base"
8317
- }
8318
- },
8319
- {
8320
- "slug": "token-source-ids",
8321
- "label": "Source IDs",
8322
- "valueType": "string",
8323
- "inputType": "textarea"
8324
- },
8325
- {
8326
- "slug": "token-json",
8327
- "label": "Tokens JSON",
8328
- "valueType": "string",
8329
- "inputType": "textarea"
8330
- },
8331
- {
8332
- "slug": "token-css",
8333
- "label": "CSS variables",
8334
- "valueType": "string",
8335
- "inputType": "textarea"
8336
- },
8337
- {
8338
- "slug": "token-notes",
8339
- "label": "Notes",
8340
- "valueType": "string",
8341
- "inputType": "textarea"
8342
- }
8343
- ]
8344
- },
8345
- {
8346
- "slug": "brand-voice-guide",
8347
- "displayName": "Voice Guide",
8348
- "icon": "message-circle",
8349
- "color": "orange",
8350
- "description": "Generated or curated voice guidance by context: traits, tone, vocabulary, and copy examples.",
8351
- "semanticSlug": "brand.voice",
8352
- "properties": [
8353
- {
8354
- "slug": "voice-context",
8355
- "label": "Context",
8356
- "valueType": "string",
8357
- "inputType": "select",
8358
- "enumValues": [
8359
- "general",
8360
- "marketing",
8361
- "product",
8362
- "support",
8363
- "social",
8364
- "legal",
8365
- "editorial",
8366
- "investor"
8367
- ],
8368
- "constraints": {
8369
- "defaultValue": "general"
8370
- }
8371
- },
8372
- {
8373
- "slug": "voice-status",
8374
- "label": "Status",
8375
- "valueType": "string",
8376
- "inputType": "select",
8377
- "enumValues": [
8378
- "draft",
8379
- "approved",
8380
- "deprecated"
8381
- ],
8382
- "constraints": {
8383
- "defaultValue": "approved"
8384
- }
8385
- },
8386
- {
8387
- "slug": "voice-personality-traits",
8388
- "label": "Personality",
8389
- "valueType": "string",
8390
- "inputType": "textarea"
8391
- },
8392
- {
8393
- "slug": "voice-tone-descriptors",
8394
- "label": "Tone",
8395
- "valueType": "string",
8396
- "inputType": "text"
8397
- },
8398
- {
8399
- "slug": "voice-vocabulary",
8400
- "label": "Vocabulary",
8401
- "valueType": "string",
8402
- "inputType": "textarea"
8403
- },
8404
- {
8405
- "slug": "voice-example-do",
8406
- "label": "Do",
8407
- "valueType": "string",
8408
- "inputType": "textarea"
8409
- },
8410
- {
8411
- "slug": "voice-example-dont",
8412
- "label": "Don't",
8413
- "valueType": "string",
8414
- "inputType": "textarea"
8415
- },
8416
- {
8417
- "slug": "voice-source-ids",
8418
- "label": "Source IDs",
8419
- "valueType": "string",
8420
- "inputType": "textarea"
8421
- }
8422
- ]
8423
- },
8424
- {
8425
- "slug": "brand-rule",
8426
- "displayName": "Brand Rule",
8427
- "icon": "shield-check",
8428
- "color": "red",
8429
- "description": "Usage constraints, accessibility requirements, do/don't examples, and generation guidance.",
8430
- "semanticSlug": "brand.rule",
8431
- "properties": [
8432
- {
8433
- "slug": "rule-kind",
8434
- "label": "Kind",
8435
- "valueType": "string",
8436
- "inputType": "select",
8437
- "enumValues": [
8438
- "visual",
8439
- "voice",
8440
- "legal",
8441
- "accessibility",
8442
- "sizing",
8443
- "clearance",
8444
- "color-usage",
8445
- "typography-usage",
8446
- "do",
8447
- "dont",
8448
- "generation",
8449
- "other"
8450
- ]
8451
- },
8452
- {
8453
- "slug": "rule-subject",
8454
- "label": "Subject",
8455
- "valueType": "string",
8456
- "inputType": "select",
8457
- "enumValues": [
8458
- "logo",
8459
- "color",
8460
- "typography",
8461
- "pattern",
8462
- "asset",
8463
- "voice",
8464
- "general",
8465
- "digital",
8466
- "print",
8467
- "packaging"
8468
- ]
8469
- },
8470
- {
8471
- "slug": "rule-severity",
8472
- "label": "Severity",
8473
- "valueType": "string",
8474
- "inputType": "select",
8475
- "enumValues": [
8476
- "guideline",
8477
- "important",
8478
- "mandatory"
8479
- ],
8480
- "constraints": {
8481
- "defaultValue": "important"
8482
- }
8483
- },
8484
- {
8485
- "slug": "rule-content",
8486
- "label": "Rule",
8487
- "valueType": "string",
8488
- "inputType": "textarea"
8489
- },
8490
- {
8491
- "slug": "rule-example",
8492
- "label": "Example",
8493
- "valueType": "string",
8494
- "inputType": "textarea"
8495
- },
8496
- {
8497
- "slug": "rule-source-ids",
8498
- "label": "Source IDs",
8499
- "valueType": "string",
8500
- "inputType": "textarea"
8501
- }
8502
- ]
8503
- },
8504
- {
8505
- "slug": "brand-template",
8506
- "displayName": "Brand Template",
8507
- "icon": "layout-template",
8508
- "color": "pink",
8509
- "description": "Reusable output template for artboards, decks, carousels, banners, documents, or generated HTML.",
8510
- "semanticSlug": "brand.template",
8511
- "properties": [
8512
- {
8513
- "slug": "template-kind",
8514
- "label": "Kind",
8515
- "valueType": "string",
8516
- "inputType": "select",
8517
- "enumValues": [
8518
- "artboard",
8519
- "deck",
8520
- "carousel",
8521
- "banner",
8522
- "document",
8523
- "html",
8524
- "social",
8525
- "other"
8526
- ]
8527
- },
8528
- {
8529
- "slug": "template-status",
8530
- "label": "Status",
8531
- "valueType": "string",
8532
- "inputType": "select",
8533
- "enumValues": [
8534
- "draft",
8535
- "approved",
8536
- "deprecated"
8537
- ],
8538
- "constraints": {
8539
- "defaultValue": "approved"
8540
- }
8541
- },
8542
- {
8543
- "slug": "template-format",
8544
- "label": "Format",
8545
- "valueType": "string",
8546
- "inputType": "select",
8547
- "enumValues": [
8548
- "tldraw",
8549
- "html",
8550
- "json",
8551
- "markdown",
8552
- "image",
8553
- "mixed"
8554
- ]
8555
- },
8556
- {
8557
- "slug": "template-config",
8558
- "label": "Config JSON",
8559
- "valueType": "string",
8560
- "inputType": "textarea"
8561
- },
8562
- {
8563
- "slug": "template-usage",
8564
- "label": "Usage notes",
8565
- "valueType": "string",
8566
- "inputType": "textarea"
8567
- }
8568
- ]
8569
- },
8570
- {
8571
- "slug": "brand-component",
8572
- "displayName": "Brand Component",
8573
- "icon": "component",
8574
- "color": "green",
8575
- "description": "Reusable branded UI or content component: hero, CTA, card, quote, banner, section, or HTML snippet.",
8576
- "semanticSlug": "brand.component",
8577
- "properties": [
8578
- {
8579
- "slug": "component-kind",
8580
- "label": "Kind",
8581
- "valueType": "string",
8582
- "inputType": "select",
8583
- "enumValues": [
8584
- "hero",
8585
- "card",
8586
- "cta",
8587
- "quote",
8588
- "banner",
8589
- "section",
8590
- "layout",
8591
- "html",
8592
- "other"
8593
- ]
8594
- },
8595
- {
8596
- "slug": "component-status",
8597
- "label": "Status",
8598
- "valueType": "string",
8599
- "inputType": "select",
8600
- "enumValues": [
8601
- "draft",
8602
- "approved",
8603
- "deprecated"
8604
- ],
8605
- "constraints": {
8606
- "defaultValue": "approved"
8607
- }
8608
- },
8609
- {
8610
- "slug": "component-html",
8611
- "label": "HTML",
8612
- "valueType": "string",
8613
- "inputType": "textarea"
8614
- },
8615
- {
8616
- "slug": "component-props",
8617
- "label": "Props JSON",
8618
- "valueType": "string",
8619
- "inputType": "textarea"
8620
- },
8621
- {
8622
- "slug": "component-usage",
8623
- "label": "Usage notes",
8624
- "valueType": "string",
8625
- "inputType": "textarea"
8626
- }
8627
- ]
8628
- },
8629
- {
8630
- "slug": "positioning",
8631
- "displayName": "Positioning",
8632
- "icon": "crosshair",
8633
- "color": "cyan",
8634
- "description": "Market category, who we stand against, and why we win.",
8635
- "properties": [
8636
- {
8637
- "slug": "category",
8638
- "label": "Category",
8639
- "valueType": "string",
8640
- "inputType": "text"
8641
- },
8642
- {
8643
- "slug": "against",
8644
- "label": "Against",
8645
- "valueType": "string",
8646
- "inputType": "textarea"
8647
- },
8648
- {
8649
- "slug": "because",
8650
- "label": "Because",
8651
- "valueType": "string",
8652
- "inputType": "textarea"
8653
- }
8654
- ]
8655
- },
8656
- {
8657
- "slug": "narrative",
8658
- "displayName": "Narrative",
8659
- "icon": "book-open",
8660
- "color": "amber",
8661
- "description": "The origin -> insight -> mission story arc.",
8662
- "properties": [
8663
- {
8664
- "slug": "arc",
8665
- "label": "Story arc",
8666
- "valueType": "string",
8667
- "inputType": "textarea"
8668
- },
8669
- {
8670
- "slug": "status",
8671
- "label": "Status",
8672
- "valueType": "string",
8673
- "inputType": "select",
8674
- "enumValues": [
8675
- "draft",
8676
- "active",
8677
- "archived"
8678
- ],
8679
- "constraints": {
8680
- "defaultValue": "active"
8681
- }
8682
- }
8683
- ]
8684
- },
8685
- {
8686
- "slug": "audience",
8687
- "displayName": "Audience",
8688
- "icon": "users",
8689
- "color": "blue",
8690
- "description": "An ideal customer profile \u2014 who we are built for.",
8691
- "properties": [
8692
- {
8693
- "slug": "segment",
8694
- "label": "Segment",
8695
- "valueType": "string",
8696
- "inputType": "text"
8697
- },
8698
- {
8699
- "slug": "persona",
8700
- "label": "Persona",
8701
- "valueType": "string",
8702
- "inputType": "textarea"
8703
- },
8704
- {
8705
- "slug": "jobs-to-be-done",
8706
- "label": "Jobs to be done",
8707
- "valueType": "string",
8708
- "inputType": "textarea"
8709
- },
8710
- {
8711
- "slug": "traits",
8712
- "label": "Traits",
8713
- "valueType": "array",
8714
- "inputType": "text"
8715
- }
8716
- ]
8717
- },
8718
- {
8719
- "slug": "differentiator",
8720
- "displayName": "Differentiator",
8721
- "icon": "sparkles",
8722
- "color": "green",
8723
- "description": "One thing only we do, believe, or refuse.",
8724
- "properties": [
8725
- {
8726
- "slug": "statement",
8727
- "label": "Statement",
8728
- "valueType": "string",
8729
- "inputType": "textarea"
8730
- },
8731
- {
8732
- "slug": "proof",
8733
- "label": "Proof",
7939
+ "slug": "proof",
7940
+ "label": "Proof",
8734
7941
  "valueType": "string",
8735
7942
  "inputType": "textarea"
8736
7943
  }
@@ -8905,6 +8112,7 @@ var DATA = {
8905
8112
  "content-os": {
8906
8113
  "meta": {
8907
8114
  "slug": "content-os",
8115
+ "domain": "content",
8908
8116
  "name": "Content OS",
8909
8117
  "description": "Your editorial operating system \u2014 pillars, posts, platforms, and newsletters. Turn raw thinking into a published content engine, all connected to your campaigns and brand voice.",
8910
8118
  "icon": "pen-tool",
@@ -9184,7 +8392,7 @@ var DATA = {
9184
8392
  "icon": "share-2",
9185
8393
  "color": "#06B6D4",
9186
8394
  "description": "A social account, newsletter publication, or podcast channel. Each platform has its own audience metrics and publishing rhythm.",
9187
- "scope": "WORKSPACE",
8395
+ "scope": "shared",
9188
8396
  "properties": [
9189
8397
  {
9190
8398
  "slug": "platform-type",
@@ -9205,6 +8413,13 @@ var DATA = {
9205
8413
  "Other"
9206
8414
  ]
9207
8415
  },
8416
+ {
8417
+ "slug": "handle",
8418
+ "label": "Handle",
8419
+ "valueType": "string",
8420
+ "inputType": "text",
8421
+ "placeholder": "@username"
8422
+ },
9208
8423
  {
9209
8424
  "slug": "platform-status",
9210
8425
  "label": "Status",
@@ -9740,6 +8955,7 @@ var DATA = {
9740
8955
  "content-studio": {
9741
8956
  "meta": {
9742
8957
  "slug": "content-studio",
8958
+ "domain": "content",
9743
8959
  "name": "Content Studio",
9744
8960
  "description": "HyperFrames + Remotion video pipeline \u2014 script, design, compose, render, publish.",
9745
8961
  "icon": "clapperboard",
@@ -10275,6 +9491,7 @@ var DATA = {
10275
9491
  "crm": {
10276
9492
  "meta": {
10277
9493
  "slug": "crm",
9494
+ "domain": "revenue",
10278
9495
  "name": "CRM",
10279
9496
  "description": "Sales pipeline and contact management from first contact to handoff.",
10280
9497
  "icon": "handshake",
@@ -10497,6 +9714,22 @@ var DATA = {
10497
9714
  "inactive"
10498
9715
  ]
10499
9716
  },
9717
+ {
9718
+ "slug": "commercialStage",
9719
+ "label": "Commercial stage",
9720
+ "valueType": "string",
9721
+ "inputType": "select",
9722
+ "enumValues": [
9723
+ "draft",
9724
+ "proposed",
9725
+ "negotiating",
9726
+ "won",
9727
+ "lost"
9728
+ ],
9729
+ "constraints": {
9730
+ "defaultValue": "draft"
9731
+ }
9732
+ },
10500
9733
  {
10501
9734
  "slug": "valueType",
10502
9735
  "label": "Value type",
@@ -10844,6 +10077,7 @@ var DATA = {
10844
10077
  "dev-dashboard": {
10845
10078
  "meta": {
10846
10079
  "slug": "dev-dashboard",
10080
+ "domain": "build",
10847
10081
  "name": "Synap Dev \u2014 Infrastructure Command Center",
10848
10082
  "description": "Internal DevOps dashboard for monitoring Synap infrastructure. Tracks services, vendors, and environments with health status, architecture flow map, and quick access to admin panels.",
10849
10083
  "icon": "server",
@@ -12554,6 +11788,7 @@ var DATA = {
12554
11788
  "ecosystem": {
12555
11789
  "meta": {
12556
11790
  "slug": "ecosystem",
11791
+ "domain": "strategy",
12557
11792
  "name": "Ecosystem",
12558
11793
  "description": "Map the market you operate in \u2014 the partners, competitors, and players, the segments and trends, and the relationships between them.",
12559
11794
  "icon": "radar",
@@ -13300,6 +12535,7 @@ var DATA = {
13300
12535
  "enterprise-os": {
13301
12536
  "meta": {
13302
12537
  "slug": "enterprise-os",
12538
+ "domain": "company",
13303
12539
  "name": "Enterprise OS",
13304
12540
  "description": "Stand up a company's public operating core in one install \u2014 strategy, market, operations, and pipeline \u2014 plus a command tower to track objectives across them.",
13305
12541
  "icon": "layout-dashboard",
@@ -13340,6 +12576,12 @@ var DATA = {
13340
12576
  "relation": "require",
13341
12577
  "reason": "The pipeline \u2014 contacts, leads, clients, and deals."
13342
12578
  },
12579
+ {
12580
+ "slug": "business-developer",
12581
+ "kind": "workspace",
12582
+ "relation": "require",
12583
+ "reason": "The lead-first sales motion (crm-lead/crm-client roles, commercial proposals, commission handoff) that the CRM app runs on. Composes onto the CRM workspace above \u2014 without it the CRM lens is provisioned with pod-wide lead/client only and the app's pipeline is empty."
12584
+ },
13343
12585
  {
13344
12586
  "slug": "content-os",
13345
12587
  "kind": "workspace",
@@ -13536,6 +12778,7 @@ var DATA = {
13536
12778
  "finance": {
13537
12779
  "meta": {
13538
12780
  "slug": "finance",
12781
+ "domain": "company",
13539
12782
  "name": "Finance",
13540
12783
  "description": "The company's money model \u2014 accounts, receivables, spend, revenue streams, budgets, and runway.",
13541
12784
  "icon": "banknote",
@@ -14377,6 +13620,7 @@ var DATA = {
14377
13620
  "foundation": {
14378
13621
  "meta": {
14379
13622
  "slug": "foundation",
13623
+ "domain": "strategy",
14380
13624
  "name": "Foundation",
14381
13625
  "description": "The strategic DNA \u2014 mission, audience, positioning, and principles \u2014 that every workspace inherits.",
14382
13626
  "icon": "compass",
@@ -15217,6 +14461,7 @@ var DATA = {
15217
14461
  "grants": {
15218
14462
  "meta": {
15219
14463
  "slug": "grants",
14464
+ "domain": "revenue",
15220
14465
  "name": "Grants Pipeline",
15221
14466
  "description": "Grant-agency operations \u2014 submissions, rounds, analyses. Overlays the Operations workspace.",
15222
14467
  "icon": "award",
@@ -16692,6 +15937,7 @@ var DATA = {
16692
15937
  "hr": {
16693
15938
  "meta": {
16694
15939
  "slug": "hr",
15940
+ "domain": "company",
16695
15941
  "name": "HR",
16696
15942
  "description": "The people operating system \u2014 team, hiring, performance reviews, and policies in one place.",
16697
15943
  "icon": "users-round",
@@ -17518,6 +16764,7 @@ var DATA = {
17518
16764
  "internal-runbook": {
17519
16765
  "meta": {
17520
16766
  "slug": "internal-runbook",
16767
+ "domain": "company",
17521
16768
  "name": "Internal Runbook",
17522
16769
  "description": "The company's operating system \u2014 SOPs, workflows, vendors, tools, metrics, and rituals that keep the business running.",
17523
16770
  "icon": "settings-2",
@@ -17533,7 +16780,6 @@ var DATA = {
17533
16780
  "workspace": {
17534
16781
  "name": "Internal Runbook",
17535
16782
  "description": "The operating layer of the company \u2014 documented procedures, recurring processes, the tool stack and vendors behind them, operational metrics, and the rituals that keep the team aligned.",
17536
- "proposalId": "operations-v1",
17537
16783
  "subtype": "internal-runbook",
17538
16784
  "visibility": "members",
17539
16785
  "workspaceType": "operational",
@@ -18354,6 +17600,7 @@ var DATA = {
18354
17600
  "legal": {
18355
17601
  "meta": {
18356
17602
  "slug": "legal",
17603
+ "domain": "company",
18357
17604
  "name": "Legal",
18358
17605
  "description": "The company's legal operating system \u2014 contracts, compliance, IP, entities, and matters.",
18359
17606
  "icon": "scale",
@@ -19217,6 +18464,7 @@ var DATA = {
19217
18464
  "life-os": {
19218
18465
  "meta": {
19219
18466
  "slug": "life-os",
18467
+ "domain": "knowledge",
19220
18468
  "name": "Second Brain \u2014 Knowledge OS",
19221
18469
  "description": "A sovereign personal knowledge management workspace. Capture everything, connect ideas, build your external brain.",
19222
18470
  "icon": "brain",
@@ -22050,6 +21298,7 @@ var DATA = {
22050
21298
  "marketing-campaign": {
22051
21299
  "meta": {
22052
21300
  "slug": "marketing-campaign",
21301
+ "domain": "revenue",
22053
21302
  "name": "Marketing Campaigns",
22054
21303
  "description": "Track leads, manage campaigns, and let AI help run your outreach. Contacts, pipeline, tasks, and AI briefings \u2014 all connected.",
22055
21304
  "icon": "megaphone",
@@ -22481,6 +21730,7 @@ var DATA = {
22481
21730
  "meetings-knowledge": {
22482
21731
  "meta": {
22483
21732
  "slug": "meetings-knowledge",
21733
+ "domain": "knowledge",
22484
21734
  "name": "Meetings & Knowledge",
22485
21735
  "description": "Import and summarize meetings \u2014 transcripts become notes, action items become tasks, and attendees become tracked people.",
22486
21736
  "icon": "video",
@@ -22860,6 +22110,7 @@ var DATA = {
22860
22110
  "operations": {
22861
22111
  "meta": {
22862
22112
  "slug": "operations",
22113
+ "domain": "company",
22863
22114
  "name": "Operations",
22864
22115
  "description": "Deliver client work end to end \u2014 the engagements you're running, the deliverables due inside them, and the contracts that govern them. Won deals from CRM hand off into engagements here.",
22865
22116
  "icon": "briefcase",
@@ -22887,6 +22138,14 @@ var DATA = {
22887
22138
  "operations": "provider"
22888
22139
  }
22889
22140
  },
22141
+ "dependencies": [
22142
+ {
22143
+ "slug": "foundation",
22144
+ "kind": "workspace",
22145
+ "relation": "require",
22146
+ "reason": "Provides the pod-wide `client` role the daily client-briefing automation queries."
22147
+ }
22148
+ ],
22890
22149
  "profiles": [
22891
22150
  {
22892
22151
  "slug": "engagement",
@@ -23074,6 +22333,72 @@ var DATA = {
23074
22333
  "inputType": "textarea"
23075
22334
  }
23076
22335
  ]
22336
+ },
22337
+ {
22338
+ "slug": "client-briefing",
22339
+ "displayName": "Client Briefing",
22340
+ "icon": "newspaper",
22341
+ "color": "#F59E0B",
22342
+ "description": "A dated internal recap of one client's recent communications \u2014 what moved, what's at risk, what's next. For the team, never for the client.",
22343
+ "properties": [
22344
+ {
22345
+ "slug": "briefing-client",
22346
+ "label": "Client",
22347
+ "valueType": "entity_id",
22348
+ "targetProfileSlug": "company",
22349
+ "inputType": "entity_select"
22350
+ },
22351
+ {
22352
+ "slug": "briefing-date",
22353
+ "label": "Written At",
22354
+ "valueType": "date",
22355
+ "inputType": "date"
22356
+ },
22357
+ {
22358
+ "slug": "briefing-key",
22359
+ "label": "Run Key",
22360
+ "valueType": "string",
22361
+ "inputType": "text"
22362
+ },
22363
+ {
22364
+ "slug": "briefing-headline",
22365
+ "label": "Headline",
22366
+ "valueType": "string",
22367
+ "inputType": "text"
22368
+ },
22369
+ {
22370
+ "slug": "briefing-summary",
22371
+ "label": "Summary",
22372
+ "valueType": "string",
22373
+ "inputType": "textarea"
22374
+ },
22375
+ {
22376
+ "slug": "briefing-risks",
22377
+ "label": "Risks",
22378
+ "valueType": "string",
22379
+ "inputType": "textarea"
22380
+ },
22381
+ {
22382
+ "slug": "briefing-next-actions",
22383
+ "label": "Next Actions",
22384
+ "valueType": "string",
22385
+ "inputType": "textarea"
22386
+ },
22387
+ {
22388
+ "slug": "briefing-message-count",
22389
+ "label": "Messages Read",
22390
+ "valueType": "number",
22391
+ "inputType": "number"
22392
+ }
22393
+ ]
22394
+ }
22395
+ ],
22396
+ "entityLinks": [
22397
+ {
22398
+ "sourceProfileSlug": "client-briefing",
22399
+ "targetProfileSlug": "company",
22400
+ "type": "briefing_about_client",
22401
+ "label": "Client"
23077
22402
  }
23078
22403
  ],
23079
22404
  "views": [
@@ -23099,6 +22424,13 @@ var DATA = {
23099
22424
  "type": "table",
23100
22425
  "scopeProfileSlug": "contract",
23101
22426
  "description": "Contracts with their status, value, and term."
22427
+ },
22428
+ {
22429
+ "name": "Client Briefings",
22430
+ "slug": "client-briefings",
22431
+ "type": "list",
22432
+ "scopeProfileSlug": "client-briefing",
22433
+ "description": "The daily internal recaps, newest first."
23102
22434
  }
23103
22435
  ],
23104
22436
  "onboarding": {
@@ -23188,12 +22520,259 @@ var DATA = {
23188
22520
  "h": 5
23189
22521
  }
23190
22522
  }
23191
- ]
23192
- }
22523
+ ]
22524
+ },
22525
+ "automations": [
22526
+ {
22527
+ "key": "operations-daily-client-briefing",
22528
+ "name": "Daily client briefing",
22529
+ "description": "Operations-native daily client briefing. Writes a durable, dated client-briefing ENTITY per client (queryable history, linked to the client) from their recent comms, and posts the recap to the client's internal TEAM channel (never the client-facing channel). Knowledge-building and entity-first \u2014 the delivery OS's structured memory of each client. For a lighter, portable message-only digest installable on any pod, use the client-comms-report capability.",
22530
+ "triggerType": "cron",
22531
+ "triggerConfig": {
22532
+ "expression": "0 8 * * *"
22533
+ },
22534
+ "status": "active",
22535
+ "metadata": {
22536
+ "templateKey": "operations-daily-client-briefing",
22537
+ "requiresPodWideEntityQueryLens": true
22538
+ },
22539
+ "flow": {
22540
+ "nodes": [
22541
+ {
22542
+ "id": "trigger",
22543
+ "type": "trigger",
22544
+ "position": {
22545
+ "x": 0,
22546
+ "y": 0
22547
+ },
22548
+ "data": {
22549
+ "label": "Daily at 08:00",
22550
+ "triggerType": "cron",
22551
+ "config": {
22552
+ "expression": "0 8 * * *"
22553
+ }
22554
+ }
22555
+ },
22556
+ {
22557
+ "id": "list-clients",
22558
+ "type": "capability",
22559
+ "position": {
22560
+ "x": 0,
22561
+ "y": 120
22562
+ },
22563
+ "data": {
22564
+ "label": "List clients (pod-wide `client` role)",
22565
+ "verbId": "entity.query",
22566
+ "inputMapping": {
22567
+ "profileSlug": "client",
22568
+ "scope": "pod",
22569
+ "limit": "100"
22570
+ }
22571
+ }
22572
+ },
22573
+ {
22574
+ "id": "clients-loop",
22575
+ "type": "loop",
22576
+ "position": {
22577
+ "x": 0,
22578
+ "y": 240
22579
+ },
22580
+ "data": {
22581
+ "label": "For each client",
22582
+ "iteratorExpression": "steps.list-clients.output.entities",
22583
+ "itemVariable": "client"
22584
+ }
22585
+ },
22586
+ {
22587
+ "id": "read-comms",
22588
+ "type": "messages_query",
22589
+ "position": {
22590
+ "x": 0,
22591
+ "y": 360
22592
+ },
22593
+ "data": {
22594
+ "label": "Read this client's recent comms",
22595
+ "subjectEntityId": "{{loop.item.id}}",
22596
+ "limit": 40
22597
+ }
22598
+ },
22599
+ {
22600
+ "id": "digest",
22601
+ "type": "capability",
22602
+ "position": {
22603
+ "x": 0,
22604
+ "y": 480
22605
+ },
22606
+ "data": {
22607
+ "label": "Distil the real signal \u2192 JSON",
22608
+ "verbId": "ai.generate",
22609
+ "inputMapping": {
22610
+ "json": "true",
22611
+ "maxTokens": "1200",
22612
+ "system": "You advise a client-delivery team. You read one client's recent inbound messages and surface only what genuinely matters. You are firewall-aware: your output is for the INTERNAL team, never the client.",
22613
+ "prompt": `Digest the recent communications for the client "{{loop.item.title}}" into a concise internal briefing for OUR delivery team.
22614
+ PEOPLE GUARD (do not break): distinguish the CLIENT's people from OUR team members who also appear in the thread. Never treat a teammate as a client contact, lead, or new person. Only real, client-side signal counts.
22615
+ Surface ONLY real signal: status changes, decisions, deals/opportunities, competitor mentions, new client-side leads/contacts, risks/blockers, and deadlines/commitments. Skip small talk and noise. Lead with what matters; keep it tight.
22616
+ Respond with STRICT JSON and NOTHING else: {
22617
+ "hasSignal": "true" or "false" (a STRING),
22618
+ "headline": "<one-line summary; empty string when hasSignal is 'false'>",
22619
+ "summary": "<a short markdown digest for the team; empty string when 'false'>",
22620
+ "risks": "<risks/blockers as short markdown, or empty string>",
22621
+ "nextActions": "<recommended next actions as short markdown, or empty string>"
22622
+ } Set hasSignal to "false" when there is no notable activity (no messages, or only chatter).
22623
+ Recent conversation (oldest first, JSON): {{steps.read-comms.output.messages}}`
22624
+ }
22625
+ }
22626
+ },
22627
+ {
22628
+ "id": "signal-gate",
22629
+ "type": "condition",
22630
+ "position": {
22631
+ "x": 0,
22632
+ "y": 600
22633
+ },
22634
+ "data": {
22635
+ "label": "Only continue when there's real signal",
22636
+ "expression": "steps.digest.output.hasSignal === true"
22637
+ }
22638
+ },
22639
+ {
22640
+ "id": "write-briefing",
22641
+ "type": "output",
22642
+ "position": {
22643
+ "x": 0,
22644
+ "y": 720
22645
+ },
22646
+ "data": {
22647
+ "label": "Save the client briefing",
22648
+ "outputType": "entity_create",
22649
+ "config": {
22650
+ "profileSlug": "client-briefing",
22651
+ "title": "Briefing \u2014 {{loop.item.title}}",
22652
+ "dedupeBy": "briefing-key",
22653
+ "properties": {
22654
+ "briefing-key": "{{loop.item.id}}::{{trigger.payload.scheduledAt}}",
22655
+ "briefing-client": "{{loop.item.id}}",
22656
+ "briefing-date": "{{trigger.payload.scheduledAt}}",
22657
+ "briefing-headline": "{{steps.digest.output.headline}}",
22658
+ "briefing-summary": "{{steps.digest.output.summary}}",
22659
+ "briefing-risks": "{{steps.digest.output.risks}}",
22660
+ "briefing-next-actions": "{{steps.digest.output.nextActions}}",
22661
+ "briefing-message-count": "{{steps.read-comms.output.count}}"
22662
+ }
22663
+ }
22664
+ }
22665
+ },
22666
+ {
22667
+ "id": "link-briefing",
22668
+ "type": "output",
22669
+ "position": {
22670
+ "x": 0,
22671
+ "y": 840
22672
+ },
22673
+ "data": {
22674
+ "label": "Link briefing \u2192 client",
22675
+ "outputType": "relation_create",
22676
+ "config": {
22677
+ "fromEntityId": "{{steps.write-briefing.output.entityId}}",
22678
+ "toEntityId": "{{loop.item.id}}",
22679
+ "relationType": "briefing_about_client"
22680
+ }
22681
+ }
22682
+ },
22683
+ {
22684
+ "id": "resolve-team",
22685
+ "type": "capability",
22686
+ "position": {
22687
+ "x": 0,
22688
+ "y": 960
22689
+ },
22690
+ "data": {
22691
+ "label": "Resolve the client's TEAM channel (FIREWALL)",
22692
+ "verbId": "channel.resolve",
22693
+ "inputMapping": {
22694
+ "contextObjectType": "entity",
22695
+ "contextObjectId": "{{loop.item.id}}",
22696
+ "branchPurpose": "team"
22697
+ }
22698
+ }
22699
+ },
22700
+ {
22701
+ "id": "post-recap",
22702
+ "type": "output",
22703
+ "position": {
22704
+ "x": 0,
22705
+ "y": 1080
22706
+ },
22707
+ "data": {
22708
+ "label": "Post the recap to the TEAM channel (FIREWALL)",
22709
+ "outputType": "channel_message",
22710
+ "config": {
22711
+ "channelId": "{{steps.resolve-team.output.channelId}}",
22712
+ "content": "**{{loop.item.title}} \u2014 daily briefing**\n{{steps.digest.output.headline}}\n{{steps.digest.output.summary}}\n**Risks:** {{steps.digest.output.risks}}\n**Next:** {{steps.digest.output.nextActions}}",
22713
+ "metadata": {
22714
+ "automationMessage": true,
22715
+ "kind": "client-briefing"
22716
+ }
22717
+ }
22718
+ }
22719
+ }
22720
+ ],
22721
+ "edges": [
22722
+ {
22723
+ "id": "e-trigger-list",
22724
+ "source": "trigger",
22725
+ "target": "list-clients"
22726
+ },
22727
+ {
22728
+ "id": "e-list-loop",
22729
+ "source": "list-clients",
22730
+ "target": "clients-loop"
22731
+ },
22732
+ {
22733
+ "id": "e-loop-read",
22734
+ "source": "clients-loop",
22735
+ "target": "read-comms"
22736
+ },
22737
+ {
22738
+ "id": "e-read-digest",
22739
+ "source": "read-comms",
22740
+ "target": "digest"
22741
+ },
22742
+ {
22743
+ "id": "e-digest-gate",
22744
+ "source": "digest",
22745
+ "target": "signal-gate"
22746
+ },
22747
+ {
22748
+ "id": "e-gate-write",
22749
+ "source": "signal-gate",
22750
+ "target": "write-briefing"
22751
+ },
22752
+ {
22753
+ "id": "e-write-link",
22754
+ "source": "write-briefing",
22755
+ "target": "link-briefing"
22756
+ },
22757
+ {
22758
+ "id": "e-link-resolve",
22759
+ "source": "link-briefing",
22760
+ "target": "resolve-team"
22761
+ },
22762
+ {
22763
+ "id": "e-resolve-post",
22764
+ "source": "resolve-team",
22765
+ "target": "post-recap"
22766
+ }
22767
+ ]
22768
+ }
22769
+ }
22770
+ ]
23193
22771
  },
23194
22772
  "outreach-comms": {
23195
22773
  "meta": {
23196
22774
  "slug": "outreach-comms",
22775
+ "domain": "revenue",
23197
22776
  "name": "Outreach & Comms",
23198
22777
  "description": "Personalized LinkedIn and email outreach \u2014 sequenced touches against real people and companies, drafted and sent by an agent.",
23199
22778
  "icon": "send",
@@ -23477,360 +23056,131 @@ var DATA = {
23477
23056
  },
23478
23057
  {
23479
23058
  "name": "channel",
23480
- "type": "choice",
23481
- "label": "Channel",
23482
- "defaultValue": "linkedin"
23483
- },
23484
- {
23485
- "name": "campaignContext",
23486
- "type": "text",
23487
- "label": "Value prop + call to action"
23488
- }
23489
- ],
23490
- "executor": "is-agent",
23491
- "grants": [
23492
- "linkedin_send_invite",
23493
- "unipile_send_message",
23494
- "gmail_send",
23495
- "entity.create"
23496
- ],
23497
- "status": "active"
23498
- }
23499
- ],
23500
- "integrations": [
23501
- {
23502
- "templateKey": "unipile-linkedin"
23503
- },
23504
- {
23505
- "templateKey": "nango-google"
23506
- }
23507
- ],
23508
- "onboarding": {
23509
- "goal": "Stand up an outreach motion \u2014 who we're targeting, on which channel, with what offer \u2014 so the agent can start drafting and sending real touches instead of waiting for a blank campaign.\n",
23510
- "framing": 'THE OUTBOUND LEAD: Act as a sharp SDR/outbound lead. Push for a SPECIFIC\nsegment and a SPECIFIC offer, not "reach out to everyone about our product".\nA campaign with no segment and no value prop is just a contact list.\n',
23511
- "expertise": {
23512
- "starters": [
23513
- 'Name the segment as a person, not a market \u2014 "Head of Growth at seed-to-Series-A B2B SaaS", not "SaaS companies". The agent personalizes against a person, not a category.\n',
23514
- 'Every campaign needs ONE call to action, stated plainly \u2014 a call, a demo, a reply. If the founder gives a vague goal ("build awareness"), push for the concrete next step a touch should provoke.\n'
23515
- ],
23516
- "blindSpots": [
23517
- "Founders default to email when LinkedIn converts better for cold B2B \u2014 ask which channel the target segment actually lives on before defaulting.\n",
23518
- "A campaign with no target contacts yet is fine to create, but flag it \u2014 the first touch needs at least one real person or company to reach.\n"
23519
- ],
23520
- "bar": "At least one real campaign exists with a named segment, a stated value prop and call to action, and \u2014 ideally \u2014 a first target contact ready for the Personalized Outreach playbook to run against.\n"
23521
- },
23522
- "collect": [
23523
- {
23524
- "profileSlug": "outreach-campaign",
23525
- "what": "The outreach sequences to run \u2014 channel, target segment, and offer.",
23526
- "cardinality": "few",
23527
- "keyFields": [
23528
- "channel",
23529
- "targetSegment",
23530
- "valueProp",
23531
- "callToAction"
23532
- ]
23533
- },
23534
- {
23535
- "profileSlug": "person",
23536
- "what": "The first contacts to target with this campaign.",
23537
- "cardinality": "few",
23538
- "keyFields": [
23539
- "email"
23540
- ]
23541
- }
23542
- ],
23543
- "openingQuestions": [
23544
- "Who are you trying to reach \u2014 what role, at what kind of company?",
23545
- "LinkedIn, email, or both?",
23546
- "What's the one thing you want them to do after reading your message?"
23547
- ],
23548
- "doneWhen": "At least one campaign captured with a channel, segment, and value prop, plus one target contact."
23549
- },
23550
- "app": {
23551
- "kind": "stored",
23552
- "cellKey": "entity-detail"
23553
- },
23554
- "layout": {
23555
- "defaultView": "Campaigns",
23556
- "defaultApp": null,
23557
- "pinnedApps": [
23558
- "dashboard",
23559
- "data",
23560
- "chat"
23561
- ],
23562
- "sidebarItems": [
23563
- {
23564
- "kind": "view",
23565
- "viewName": "Campaigns",
23566
- "label": "Campaigns",
23567
- "icon": "target"
23568
- },
23569
- {
23570
- "kind": "view",
23571
- "viewName": "Touches",
23572
- "label": "Touches",
23573
- "icon": "message-circle"
23574
- },
23575
- {
23576
- "kind": "app",
23577
- "appId": "data",
23578
- "label": "Data",
23579
- "icon": "database"
23580
- }
23581
- ]
23582
- },
23583
- "bento": {
23584
- "viewName": "Outreach Home",
23585
- "blocks": [
23586
- {
23587
- "kind": "view",
23588
- "viewName": "Campaigns",
23589
- "pos": {
23590
- "x": 0,
23591
- "y": 0,
23592
- "w": 8,
23593
- "h": 5
23594
- }
23595
- },
23596
- {
23597
- "kind": "view",
23598
- "viewName": "Touches",
23599
- "pos": {
23600
- "x": 8,
23601
- "y": 0,
23602
- "w": 4,
23603
- "h": 5
23604
- }
23605
- }
23606
- ]
23607
- }
23608
- },
23609
- "personal": {
23610
- "meta": {
23611
- "slug": "personal",
23612
- "name": "Personal Knowledge",
23613
- "description": "Capture notes, bookmarks, and articles \u2014 your AI-organized second brain.",
23614
- "icon": "brain",
23615
- "color": "#0891B2",
23616
- "tags": [
23617
- "personal",
23618
- "knowledge",
23619
- "notes",
23620
- "second-brain"
23621
- ],
23622
- "isPublic": true
23623
- },
23624
- "workspace": {
23625
- "name": "Personal",
23626
- "description": "Your personal knowledge base \u2014 capture anything, let AI organize it.",
23627
- "proposalId": "personal-v1",
23628
- "subtype": "personal",
23629
- "visibility": "pod_visible",
23630
- "capabilities": [
23631
- "knowledge.capture",
23632
- "knowledge.organize"
23633
- ]
23634
- },
23635
- "profiles": [
23636
- {
23637
- "slug": "note",
23638
- "displayName": "Note",
23639
- "icon": "file-text",
23640
- "color": "amber",
23641
- "description": "A quick note or idea.",
23642
- "properties": [
23643
- {
23644
- "slug": "tags",
23645
- "label": "Tags",
23646
- "valueType": "array",
23647
- "inputType": "text"
23648
- }
23649
- ]
23650
- },
23651
- {
23652
- "slug": "bookmark",
23653
- "displayName": "Bookmark",
23654
- "icon": "bookmark",
23655
- "color": "blue",
23656
- "description": "A saved URL or web reference.",
23657
- "properties": [
23658
- {
23659
- "slug": "url",
23660
- "label": "URL",
23661
- "valueType": "string",
23662
- "inputType": "url"
23663
- }
23664
- ]
23665
- },
23666
- {
23667
- "slug": "article",
23668
- "displayName": "Article",
23669
- "icon": "book-open",
23670
- "color": "violet",
23671
- "description": "A long-form article or reading-list item.",
23672
- "properties": [
23673
- {
23674
- "slug": "readStatus",
23675
- "label": "Status",
23676
- "valueType": "string",
23677
- "inputType": "select",
23678
- "enumValues": [
23679
- "to-read",
23680
- "reading",
23681
- "read",
23682
- "archived"
23683
- ]
23684
- },
23685
- {
23686
- "slug": "url",
23687
- "label": "Source URL",
23688
- "valueType": "string",
23689
- "inputType": "url"
23690
- }
23691
- ]
23692
- },
23693
- {
23694
- "slug": "project",
23695
- "displayName": "Project",
23696
- "icon": "folder",
23697
- "color": "green",
23698
- "description": "A project grouping related notes and references.",
23699
- "properties": [
23700
- {
23701
- "slug": "status",
23702
- "label": "Status",
23703
- "valueType": "string",
23704
- "inputType": "select",
23705
- "enumValues": [
23706
- "active",
23707
- "paused",
23708
- "done",
23709
- "archived"
23710
- ]
23059
+ "type": "choice",
23060
+ "label": "Channel",
23061
+ "defaultValue": "linkedin"
23062
+ },
23063
+ {
23064
+ "name": "campaignContext",
23065
+ "type": "text",
23066
+ "label": "Value prop + call to action"
23711
23067
  }
23712
- ]
23068
+ ],
23069
+ "executor": "is-agent",
23070
+ "grants": [
23071
+ "linkedin_send_invite",
23072
+ "unipile_send_message",
23073
+ "gmail_send",
23074
+ "entity.create"
23075
+ ],
23076
+ "status": "active"
23713
23077
  }
23714
23078
  ],
23715
- "views": [
23716
- {
23717
- "name": "Feed",
23718
- "type": "masonry",
23719
- "scopeProfileSlugs": [
23720
- "note",
23721
- "bookmark",
23722
- "article",
23723
- "project"
23724
- ],
23725
- "description": "Everything you captured, newest first."
23726
- },
23079
+ "integrations": [
23727
23080
  {
23728
- "name": "Reading List",
23729
- "type": "table",
23730
- "scopeProfileSlug": "article",
23731
- "description": "Articles to read, in progress, and read."
23081
+ "templateKey": "unipile-linkedin"
23732
23082
  },
23733
23083
  {
23734
- "name": "Bookmarks",
23735
- "type": "grid",
23736
- "scopeProfileSlug": "bookmark",
23737
- "description": "Saved web references."
23084
+ "templateKey": "nango-google"
23738
23085
  }
23739
23086
  ],
23740
23087
  "onboarding": {
23741
- "goal": "Capture the shape of the user's world \u2014 what they're working on, what they're reading and saving, and how they think \u2014 so the workspace starts grounded in who they actually are.",
23742
- "framing": "THE KNOWLEDGE COACH: Act as a gentle, thoughtful personal-knowledge coach. You're here to understand their world, not audit it \u2014 curious, warm, never pushy. Meet them where they are: a couple of honest notes beat a perfect system. Reflect back what you hear so it feels captured, not interrogated.\n",
23088
+ "goal": "Stand up an outreach motion \u2014 who we're targeting, on which channel, with what offer \u2014 so the agent can start drafting and sending real touches instead of waiting for a blank campaign.\n",
23089
+ "framing": 'THE OUTBOUND LEAD: Act as a sharp SDR/outbound lead. Push for a SPECIFIC\nsegment and a SPECIFIC offer, not "reach out to everyone about our product".\nA campaign with no segment and no value prop is just a contact list.\n',
23743
23090
  "expertise": {
23744
23091
  "starters": [
23745
- `Start from ONE real recurring need, not a structure. Ask "what do you keep losing track of?" \u2014 the tab you meant to read, the idea you forgot, the link you can't find again \u2014 and seed that single thing. A personal space earns trust by solving one nagging friction, then grows; it dies if it opens as an empty filing cabinet.
23746
- `,
23747
- "Propose the 2-3 things they ACTUALLY want to track, then stop. Most people need exactly: a place for stray notes, a reading list, and a bookmark pile. Name those, seed one item in each, and resist adding projects/tags/statuses they didn't ask for. The default here is deliberately lean \u2014 under-structure on purpose.\n",
23748
- "Mirror their own capture habit instead of imposing one. Ask what a jotted thought usually looks like for them \u2014 a link, a one-liner, a voice-note-to-self \u2014 and map the workspace to that shape. If they dump links, lead with bookmarks; if they write, lead with notes. Match reality; don't teach them a new ritual.\n"
23092
+ 'Name the segment as a person, not a market \u2014 "Head of Growth at seed-to-Series-A B2B SaaS", not "SaaS companies". The agent personalizes against a person, not a category.\n',
23093
+ 'Every campaign needs ONE call to action, stated plainly \u2014 a call, a demo, a reply. If the founder gives a vague goal ("build awareness"), push for the concrete next step a touch should provoke.\n'
23749
23094
  ],
23750
23095
  "blindSpots": [
23751
- "The productivity-system graveyard: elaborate setups \u2014 nested tags, six statuses, color-coded areas \u2014 built with enthusiasm on day one and abandoned by day seven. The failure mode is over-structuring, not under-structuring. Every field you add is a field they must maintain; keep it embarrassingly simple and let it grow later.\n",
23752
- `People try to design the "perfect system" before they have any content, and stall. Structure should emerge FROM real notes, not precede them. If they're deliberating over categories with an empty workspace, cut it short \u2014 capture three real things first, and let the shape reveal itself.
23753
- `,
23754
- 'A reading list nobody triages just becomes guilt. People pile "to-read" articles and never mark anything read or dropped, so the list rots into a backlog they avoid. Give it a lightweight status (to-read / reading / read / archived) and normalize archiving unread \u2014 a shrinking list is a healthy one.\n'
23096
+ "Founders default to email when LinkedIn converts better for cold B2B \u2014 ask which channel the target segment actually lives on before defaulting.\n",
23097
+ "A campaign with no target contacts yet is fine to create, but flag it \u2014 the first touch needs at least one real person or company to reach.\n"
23755
23098
  ],
23756
- "bar": `A GREAT result is TWO OR THREE things they genuinely care about, each with a real item already in it \u2014 not an empty scaffold. It should feel like a lean personal shelf they'll actually open tomorrow, with nothing to maintain that they didn't ask for. If it looks like a "productivity system", it's already too much.
23757
- `
23099
+ "bar": "At least one real campaign exists with a named segment, a stated value prop and call to action, and \u2014 ideally \u2014 a first target contact ready for the Personalized Outreach playbook to run against.\n"
23758
23100
  },
23759
23101
  "collect": [
23760
23102
  {
23761
- "profileSlug": "project",
23762
- "what": "The handful of things they're actively working on or care about right now.",
23103
+ "profileSlug": "outreach-campaign",
23104
+ "what": "The outreach sequences to run \u2014 channel, target segment, and offer.",
23763
23105
  "cardinality": "few",
23764
23106
  "keyFields": [
23765
- "name",
23766
- "status"
23767
- ]
23768
- },
23769
- {
23770
- "profileSlug": "note",
23771
- "what": "A few ideas, thoughts, or things on their mind \u2014 however rough.",
23772
- "cardinality": "several",
23773
- "keyFields": [
23774
- "name",
23775
- "tags"
23776
- ]
23777
- },
23778
- {
23779
- "profileSlug": "article",
23780
- "what": "What they're reading or mean to read \u2014 their reading list.",
23781
- "cardinality": "several",
23782
- "keyFields": [
23783
- "name",
23784
- "readStatus"
23107
+ "channel",
23108
+ "targetSegment",
23109
+ "valueProp",
23110
+ "callToAction"
23785
23111
  ]
23786
23112
  },
23787
23113
  {
23788
- "profileSlug": "bookmark",
23789
- "what": "Web references and links worth keeping.",
23790
- "cardinality": "several",
23114
+ "profileSlug": "person",
23115
+ "what": "The first contacts to target with this campaign.",
23116
+ "cardinality": "few",
23791
23117
  "keyFields": [
23792
- "name",
23793
- "url"
23118
+ "email"
23794
23119
  ]
23795
23120
  }
23796
23121
  ],
23797
23122
  "openingQuestions": [
23798
- "What are you working on or thinking about most these days?",
23799
- "What have you been reading, saving, or meaning to get to?",
23800
- "When you jot something down, what does it usually look like \u2014 a link, a note, a task?"
23123
+ "Who are you trying to reach \u2014 what role, at what kind of company?",
23124
+ "LinkedIn, email, or both?",
23125
+ "What's the one thing you want them to do after reading your message?"
23801
23126
  ],
23802
- "doneWhen": "at least one project or note captured, plus one thing they're reading or saving."
23127
+ "doneWhen": "At least one campaign captured with a channel, segment, and value prop, plus one target contact."
23803
23128
  },
23804
23129
  "app": {
23805
23130
  "kind": "stored",
23806
23131
  "cellKey": "entity-detail"
23807
23132
  },
23808
23133
  "layout": {
23134
+ "defaultView": "Campaigns",
23135
+ "defaultApp": null,
23809
23136
  "pinnedApps": [
23810
23137
  "dashboard",
23811
23138
  "data",
23812
23139
  "chat"
23813
23140
  ],
23814
- "defaultView": "Feed",
23815
- "defaultApp": null,
23816
23141
  "sidebarItems": [
23817
23142
  {
23818
23143
  "kind": "view",
23819
- "viewName": "Feed",
23820
- "label": "Feed",
23821
- "icon": "layout-dashboard"
23144
+ "viewName": "Campaigns",
23145
+ "label": "Campaigns",
23146
+ "icon": "target"
23822
23147
  },
23823
23148
  {
23824
23149
  "kind": "view",
23825
- "viewName": "Reading List",
23826
- "label": "Reading List",
23827
- "icon": "book-open"
23150
+ "viewName": "Touches",
23151
+ "label": "Touches",
23152
+ "icon": "message-circle"
23153
+ },
23154
+ {
23155
+ "kind": "app",
23156
+ "appId": "data",
23157
+ "label": "Data",
23158
+ "icon": "database"
23159
+ }
23160
+ ]
23161
+ },
23162
+ "bento": {
23163
+ "viewName": "Outreach Home",
23164
+ "blocks": [
23165
+ {
23166
+ "kind": "view",
23167
+ "viewName": "Campaigns",
23168
+ "pos": {
23169
+ "x": 0,
23170
+ "y": 0,
23171
+ "w": 8,
23172
+ "h": 5
23173
+ }
23828
23174
  },
23829
23175
  {
23830
23176
  "kind": "view",
23831
- "viewName": "Bookmarks",
23832
- "label": "Bookmarks",
23833
- "icon": "bookmark"
23177
+ "viewName": "Touches",
23178
+ "pos": {
23179
+ "x": 8,
23180
+ "y": 0,
23181
+ "w": 4,
23182
+ "h": 5
23183
+ }
23834
23184
  }
23835
23185
  ]
23836
23186
  }
@@ -23838,6 +23188,7 @@ var DATA = {
23838
23188
  "project-management": {
23839
23189
  "meta": {
23840
23190
  "slug": "project-management",
23191
+ "domain": "build",
23841
23192
  "name": "Project Management OS",
23842
23193
  "description": "OKR-first project management workspace. Objectives, key results, projects, sprints, and tasks as connected entities \u2014 navigable from any direction in a relationship graph. Designed for solo founders and small teams who want goal-execution alignment without per-seat overhead.",
23843
23194
  "icon": "kanban-square",
@@ -25959,14 +25310,159 @@ var DATA = {
25959
25310
  "w": 4,
25960
25311
  "h": 6
25961
25312
  }
25962
- }
25963
- ]
25964
- },
25965
- "profileEntityBentoTemplates": {
25966
- "okr": {
25313
+ }
25314
+ ]
25315
+ },
25316
+ "profileEntityBentoTemplates": {
25317
+ "okr": {
25318
+ "blocks": [
25319
+ {
25320
+ "id": "okr-eb-header",
25321
+ "kind": "widget",
25322
+ "widgetType": "entity-header",
25323
+ "pos": {
25324
+ "x": 0,
25325
+ "y": 0,
25326
+ "w": 12,
25327
+ "h": 2
25328
+ }
25329
+ },
25330
+ {
25331
+ "id": "okr-eb-props",
25332
+ "kind": "widget",
25333
+ "widgetType": "entity-properties",
25334
+ "pos": {
25335
+ "x": 0,
25336
+ "y": 2,
25337
+ "w": 4,
25338
+ "h": 8
25339
+ }
25340
+ },
25341
+ {
25342
+ "id": "okr-eb-projects",
25343
+ "kind": "widget",
25344
+ "widgetType": "entity-list",
25345
+ "pos": {
25346
+ "x": 4,
25347
+ "y": 2,
25348
+ "w": 8,
25349
+ "h": 4
25350
+ },
25351
+ "config": {
25352
+ "profileSlug": "project",
25353
+ "title": "Projects",
25354
+ "limit": 6,
25355
+ "variant": "compact"
25356
+ }
25357
+ },
25358
+ {
25359
+ "id": "okr-eb-content",
25360
+ "kind": "widget",
25361
+ "widgetType": "entity-content",
25362
+ "pos": {
25363
+ "x": 4,
25364
+ "y": 6,
25365
+ "w": 8,
25366
+ "h": 4
25367
+ }
25368
+ }
25369
+ ]
25370
+ },
25371
+ "project": {
25372
+ "blocks": [
25373
+ {
25374
+ "id": "proj-eb-header",
25375
+ "kind": "widget",
25376
+ "widgetType": "entity-header",
25377
+ "pos": {
25378
+ "x": 0,
25379
+ "y": 0,
25380
+ "w": 12,
25381
+ "h": 2
25382
+ }
25383
+ },
25384
+ {
25385
+ "id": "proj-eb-props",
25386
+ "kind": "widget",
25387
+ "widgetType": "entity-properties",
25388
+ "pos": {
25389
+ "x": 0,
25390
+ "y": 2,
25391
+ "w": 4,
25392
+ "h": 8
25393
+ }
25394
+ },
25395
+ {
25396
+ "id": "proj-eb-tasks",
25397
+ "kind": "widget",
25398
+ "widgetType": "entity-list",
25399
+ "pos": {
25400
+ "x": 4,
25401
+ "y": 2,
25402
+ "w": 8,
25403
+ "h": 4
25404
+ },
25405
+ "config": {
25406
+ "profileSlug": "task",
25407
+ "title": "Tasks",
25408
+ "limit": 8,
25409
+ "variant": "compact"
25410
+ }
25411
+ },
25412
+ {
25413
+ "id": "proj-eb-content",
25414
+ "kind": "widget",
25415
+ "widgetType": "entity-content",
25416
+ "pos": {
25417
+ "x": 4,
25418
+ "y": 6,
25419
+ "w": 8,
25420
+ "h": 4
25421
+ }
25422
+ }
25423
+ ]
25424
+ },
25425
+ "task": {
25426
+ "blocks": [
25427
+ {
25428
+ "id": "task-eb-header",
25429
+ "kind": "widget",
25430
+ "widgetType": "entity-header",
25431
+ "pos": {
25432
+ "x": 0,
25433
+ "y": 0,
25434
+ "w": 12,
25435
+ "h": 2
25436
+ }
25437
+ },
25438
+ {
25439
+ "id": "task-eb-props",
25440
+ "kind": "widget",
25441
+ "widgetType": "entity-properties",
25442
+ "pos": {
25443
+ "x": 0,
25444
+ "y": 2,
25445
+ "w": 5,
25446
+ "h": 8
25447
+ }
25448
+ },
25449
+ {
25450
+ "id": "task-eb-content",
25451
+ "kind": "widget",
25452
+ "widgetType": "entity-content",
25453
+ "pos": {
25454
+ "x": 5,
25455
+ "y": 2,
25456
+ "w": 7,
25457
+ "h": 8
25458
+ }
25459
+ }
25460
+ ]
25461
+ },
25462
+ "sprint": {
25967
25463
  "blocks": [
25968
25464
  {
25969
- "id": "okr-eb-header",
25465
+ "id": "sprint-eb-header",
25970
25466
  "kind": "widget",
25971
25467
  "widgetType": "entity-header",
25972
25468
  "pos": {
@@ -25977,272 +25473,994 @@ var DATA = {
25977
25473
  }
25978
25474
  },
25979
25475
  {
25980
- "id": "okr-eb-props",
25476
+ "id": "sprint-eb-props",
25981
25477
  "kind": "widget",
25982
25478
  "widgetType": "entity-properties",
25983
25479
  "pos": {
25984
25480
  "x": 0,
25985
25481
  "y": 2,
25986
25482
  "w": 4,
25987
- "h": 8
25483
+ "h": 6
25484
+ }
25485
+ },
25486
+ {
25487
+ "id": "sprint-eb-tasks",
25488
+ "kind": "widget",
25489
+ "widgetType": "entity-list",
25490
+ "pos": {
25491
+ "x": 4,
25492
+ "y": 2,
25493
+ "w": 8,
25494
+ "h": 6
25495
+ },
25496
+ "config": {
25497
+ "profileSlug": "task",
25498
+ "title": "Sprint Tasks",
25499
+ "limit": 10,
25500
+ "variant": "compact"
25501
+ }
25502
+ }
25503
+ ]
25504
+ }
25505
+ },
25506
+ "playbooks": [
25507
+ {
25508
+ "name": "Sprint Retrospective",
25509
+ "goalTemplate": "Run a retrospective for {sprint} to review what went well, what didn't, and what to improve next sprint.",
25510
+ "params": [
25511
+ {
25512
+ "name": "sprint",
25513
+ "type": "entity",
25514
+ "label": "Sprint",
25515
+ "required": true
25516
+ }
25517
+ ]
25518
+ }
25519
+ ],
25520
+ "onboarding": {
25521
+ "goal": "Capture the user's goals, the projects in flight, the current sprint, and who's involved \u2014 so the workspace mirrors how their team actually plans and delivers.",
25522
+ "framing": "Act as a sharp delivery lead / chief of staff. Tease out what outcomes matter this quarter, what's actively being worked, what's in the current cycle, and who owns what. Translate that into OKRs, projects, a sprint, and people.",
25523
+ "expertise": {
25524
+ "starters": [
25525
+ `Don't collect a wishlist of goals \u2014 force ONE north-star metric and 2-3 key results that move it. Propose "the single number that means this quarter succeeded" first, then the handful of measurable KRs under it. Five objectives is zero objectives; a team that's aiming at everything is aiming at nothing.
25526
+ `,
25527
+ `Capture what's actually in flight and impose a WIP limit as you go. Ask "what's genuinely being worked THIS week" \u2014 not the backlog \u2014 and if it's more than the team can finish, that's the finding. Too many projects in progress means nothing ships; the map should make the overload visible.
25528
+ `,
25529
+ 'Every project and KR gets a named owner before anything else. Lead with "who owns this?" \u2014 a goal with no owner is a hope, and it will quietly slip. Capture the person on the project the moment you capture the project; ownerless work is the first thing to surface, not the last.\n'
25530
+ ],
25531
+ "blindSpots": [
25532
+ `"Everything is P1" is the prioritization failure that guarantees the wrong things ship. When every project is Critical, priority carries no information and the team defaults to whatever's loudest. Push back on the priority field \u2014 force a real ranking, because if you can't say what's LESS important, you haven't prioritized at all.
25533
+ `,
25534
+ `A goal with no owner is a hope, and hopes don't ship. Teams write beautiful OKRs with an empty owner field, and the KR that belongs to "the team" belongs to no one. Surface every ownerless objective, project, and KR \u2014 accountability is a name, not a shared intention.
25535
+ `,
25536
+ 'Too much work-in-progress is the silent throughput killer. Founders equate "many things started" with progress, but a dozen 60%-done projects deliver nothing while three finished ones deliver value. Watch the count of In-Progress items and flag when it exceeds what the team can actually close in a cycle.\n'
25537
+ ],
25538
+ "bar": `A great result is a workspace where the line from a single north-star metric down to the task in flight this week is unbroken: one clear objective with measurable KRs, every project and goal owned by a named person, a real priority ranking (not all-P1), and a WIP that matches capacity. You can answer "are we on track, who owns the thing that's slipping, and what should we STOP to ship what matters?" in one look.
25539
+ `
25540
+ },
25541
+ "collect": [
25542
+ {
25543
+ "profileSlug": "okr",
25544
+ "what": "The goals / OKRs that define success this quarter",
25545
+ "cardinality": "few",
25546
+ "keyFields": [
25547
+ "title",
25548
+ "okr-quarter",
25549
+ "okr-owner",
25550
+ "kr1-label"
25551
+ ]
25552
+ },
25553
+ {
25554
+ "profileSlug": "project",
25555
+ "what": "The projects actively in flight and their priority",
25556
+ "cardinality": "several",
25557
+ "keyFields": [
25558
+ "title",
25559
+ "project-status",
25560
+ "project-priority",
25561
+ "project-linked-okr"
25562
+ ]
25563
+ },
25564
+ {
25565
+ "profileSlug": "sprint",
25566
+ "what": "The current cycle / sprint and its goal",
25567
+ "cardinality": "one",
25568
+ "keyFields": [
25569
+ "title",
25570
+ "sprint-goal",
25571
+ "sprint-start",
25572
+ "sprint-end"
25573
+ ]
25574
+ },
25575
+ {
25576
+ "profileSlug": "person",
25577
+ "what": "The key people on the team and their roles",
25578
+ "cardinality": "several",
25579
+ "keyFields": [
25580
+ "name",
25581
+ "person-role",
25582
+ "person-email"
25583
+ ]
25584
+ }
25585
+ ],
25586
+ "openingQuestions": [
25587
+ "What are the big outcomes you're trying to hit this quarter?",
25588
+ "What projects are actively in flight right now, and which matter most?",
25589
+ "Who's on the team, and what does each person own?"
25590
+ ],
25591
+ "doneWhen": "This quarter's goals exist, active projects are captured with priority, a current sprint is defined, and the core team is on the board."
25592
+ }
25593
+ },
25594
+ "research-base": {
25595
+ "meta": {
25596
+ "slug": "research-base",
25597
+ "domain": "knowledge",
25598
+ "name": "Research",
25599
+ "description": "A research substrate \u2014 turn a question into a fully-recorded investigation. Sources ranked (nothing dropped), hypotheses weighed, findings mapped onto a living graph of fields and concepts.",
25600
+ "icon": "microscope",
25601
+ "color": "#8B5CF6",
25602
+ "tags": [
25603
+ "research",
25604
+ "knowledge",
25605
+ "graph",
25606
+ "sources",
25607
+ "evidence",
25608
+ "learning"
25609
+ ],
25610
+ "isPublic": true
25611
+ },
25612
+ "workspace": {
25613
+ "name": "Research",
25614
+ "description": "Turn a question into a fully-recorded investigation \u2014 sources ranked, hypotheses weighed, findings mapped onto a living graph of fields and concepts.",
25615
+ "subtype": "research-base",
25616
+ "visibility": "pod_visible",
25617
+ "capabilities": [
25618
+ "research.graph",
25619
+ "research.sources"
25620
+ ],
25621
+ "sourceRoles": {
25622
+ "research": "provider"
25623
+ }
25624
+ },
25625
+ "profiles": [
25626
+ {
25627
+ "slug": "question",
25628
+ "displayName": "Question",
25629
+ "icon": "help-circle",
25630
+ "color": "blue",
25631
+ "description": "An open question driving an investigation \u2014 the thing research answers.",
25632
+ "properties": [
25633
+ {
25634
+ "slug": "questionStatus",
25635
+ "label": "Status",
25636
+ "valueType": "string",
25637
+ "inputType": "select",
25638
+ "enumValues": [
25639
+ "open",
25640
+ "exploring",
25641
+ "answered",
25642
+ "abandoned"
25643
+ ],
25644
+ "constraints": {
25645
+ "defaultValue": "open"
25646
+ }
25647
+ }
25648
+ ]
25649
+ },
25650
+ {
25651
+ "slug": "research",
25652
+ "displayName": "Research",
25653
+ "icon": "microscope",
25654
+ "color": "violet",
25655
+ "description": "An investigation \u2014 the sources consulted, the findings, the confidence, and the conclusion.",
25656
+ "properties": [
25657
+ {
25658
+ "slug": "researchStatus",
25659
+ "label": "Status",
25660
+ "valueType": "string",
25661
+ "inputType": "select",
25662
+ "enumValues": [
25663
+ "ongoing",
25664
+ "concluded",
25665
+ "abandoned"
25666
+ ],
25667
+ "constraints": {
25668
+ "defaultValue": "ongoing"
25669
+ }
25670
+ },
25671
+ {
25672
+ "slug": "conclusion",
25673
+ "label": "Conclusion",
25674
+ "valueType": "string",
25675
+ "inputType": "textarea"
25676
+ },
25677
+ {
25678
+ "slug": "researchConfidence",
25679
+ "label": "Confidence",
25680
+ "valueType": "string",
25681
+ "inputType": "select",
25682
+ "enumValues": [
25683
+ "low",
25684
+ "medium",
25685
+ "high"
25686
+ ]
25687
+ }
25688
+ ]
25689
+ },
25690
+ {
25691
+ "slug": "field",
25692
+ "displayName": "Field",
25693
+ "icon": "layers",
25694
+ "color": "indigo",
25695
+ "description": "A domain of knowledge \u2014 Mathematics, Physics, AI, Philosophy. Fields overlap and feed each other.",
25696
+ "properties": [
25697
+ {
25698
+ "slug": "description",
25699
+ "label": "Description",
25700
+ "valueType": "string",
25701
+ "inputType": "textarea"
25702
+ },
25703
+ {
25704
+ "slug": "aliases",
25705
+ "label": "Also known as",
25706
+ "valueType": "array",
25707
+ "inputType": "tags"
25708
+ }
25709
+ ]
25710
+ },
25711
+ {
25712
+ "slug": "concept",
25713
+ "displayName": "Concept",
25714
+ "icon": "lightbulb",
25715
+ "color": "amber",
25716
+ "description": "An atomic idea \u2014 Bayesian inference, gradient descent, qualia. Belongs to one or more fields; has prerequisites.",
25717
+ "properties": [
25718
+ {
25719
+ "slug": "definition",
25720
+ "label": "Definition",
25721
+ "valueType": "string",
25722
+ "inputType": "textarea"
25723
+ },
25724
+ {
25725
+ "slug": "aliases",
25726
+ "label": "Also known as",
25727
+ "valueType": "array",
25728
+ "inputType": "tags"
25729
+ }
25730
+ ]
25731
+ },
25732
+ {
25733
+ "slug": "source",
25734
+ "displayName": "Source",
25735
+ "icon": "file-text",
25736
+ "color": "cyan",
25737
+ "description": "Anything consulted \u2014 a paper, article, dataset, or post. Ranked by credibility and NEVER discarded; rejected sources are kept with a reason.",
25738
+ "properties": [
25739
+ {
25740
+ "slug": "url",
25741
+ "label": "URL",
25742
+ "valueType": "string",
25743
+ "inputType": "url"
25744
+ },
25745
+ {
25746
+ "slug": "author",
25747
+ "label": "Author",
25748
+ "valueType": "string",
25749
+ "inputType": "text"
25750
+ },
25751
+ {
25752
+ "slug": "publishedAt",
25753
+ "label": "Published",
25754
+ "valueType": "date",
25755
+ "inputType": "date"
25756
+ },
25757
+ {
25758
+ "slug": "sourceType",
25759
+ "label": "Type",
25760
+ "valueType": "string",
25761
+ "inputType": "select",
25762
+ "enumValues": [
25763
+ "paper",
25764
+ "article",
25765
+ "book",
25766
+ "dataset",
25767
+ "blog",
25768
+ "video",
25769
+ "forum",
25770
+ "other"
25771
+ ],
25772
+ "constraints": {
25773
+ "defaultValue": "article"
25988
25774
  }
25989
25775
  },
25990
25776
  {
25991
- "id": "okr-eb-projects",
25992
- "kind": "widget",
25993
- "widgetType": "entity-list",
25994
- "pos": {
25995
- "x": 4,
25996
- "y": 2,
25997
- "w": 8,
25998
- "h": 4
25999
- },
26000
- "config": {
26001
- "profileSlug": "project",
26002
- "title": "Projects",
26003
- "limit": 6,
26004
- "variant": "compact"
25777
+ "slug": "credibilityBand",
25778
+ "label": "Credibility",
25779
+ "valueType": "string",
25780
+ "inputType": "select",
25781
+ "enumValues": [
25782
+ "high",
25783
+ "medium",
25784
+ "low",
25785
+ "unknown"
25786
+ ],
25787
+ "constraints": {
25788
+ "defaultValue": "unknown"
26005
25789
  }
26006
25790
  },
26007
25791
  {
26008
- "id": "okr-eb-content",
26009
- "kind": "widget",
26010
- "widgetType": "entity-content",
26011
- "pos": {
26012
- "x": 4,
26013
- "y": 6,
26014
- "w": 8,
26015
- "h": 4
26016
- }
26017
- }
26018
- ]
26019
- },
26020
- "project": {
26021
- "blocks": [
26022
- {
26023
- "id": "proj-eb-header",
26024
- "kind": "widget",
26025
- "widgetType": "entity-header",
26026
- "pos": {
26027
- "x": 0,
26028
- "y": 0,
26029
- "w": 12,
26030
- "h": 2
25792
+ "slug": "qualityScore",
25793
+ "label": "Quality (0\u2013100)",
25794
+ "valueType": "number",
25795
+ "inputType": "number",
25796
+ "constraints": {
25797
+ "min": 0,
25798
+ "max": 100
26031
25799
  }
26032
25800
  },
26033
25801
  {
26034
- "id": "proj-eb-props",
26035
- "kind": "widget",
26036
- "widgetType": "entity-properties",
26037
- "pos": {
26038
- "x": 0,
26039
- "y": 2,
26040
- "w": 4,
26041
- "h": 8
25802
+ "slug": "status",
25803
+ "label": "Status",
25804
+ "valueType": "string",
25805
+ "inputType": "select",
25806
+ "enumValues": [
25807
+ "cited",
25808
+ "considered",
25809
+ "rejected"
25810
+ ],
25811
+ "constraints": {
25812
+ "defaultValue": "considered"
26042
25813
  }
26043
25814
  },
26044
25815
  {
26045
- "id": "proj-eb-tasks",
26046
- "kind": "widget",
26047
- "widgetType": "entity-list",
26048
- "pos": {
26049
- "x": 4,
26050
- "y": 2,
26051
- "w": 8,
26052
- "h": 4
26053
- },
26054
- "config": {
26055
- "profileSlug": "task",
26056
- "title": "Tasks",
26057
- "limit": 8,
26058
- "variant": "compact"
26059
- }
25816
+ "slug": "whyRejected",
25817
+ "label": "Why rejected",
25818
+ "valueType": "string",
25819
+ "inputType": "textarea"
26060
25820
  },
26061
25821
  {
26062
- "id": "proj-eb-content",
26063
- "kind": "widget",
26064
- "widgetType": "entity-content",
26065
- "pos": {
26066
- "x": 4,
26067
- "y": 6,
26068
- "w": 8,
26069
- "h": 4
26070
- }
25822
+ "slug": "retrievedAt",
25823
+ "label": "Retrieved",
25824
+ "valueType": "date",
25825
+ "inputType": "date"
26071
25826
  }
26072
25827
  ]
26073
25828
  },
26074
- "task": {
26075
- "blocks": [
25829
+ {
25830
+ "slug": "hypothesis",
25831
+ "displayName": "Hypothesis",
25832
+ "icon": "git-branch",
25833
+ "color": "violet",
25834
+ "description": "A candidate theory or answer under test \u2014 argued for and against by sources.",
25835
+ "properties": [
26076
25836
  {
26077
- "id": "task-eb-header",
26078
- "kind": "widget",
26079
- "widgetType": "entity-header",
26080
- "pos": {
26081
- "x": 0,
26082
- "y": 0,
26083
- "w": 12,
26084
- "h": 2
26085
- }
25837
+ "slug": "statement",
25838
+ "label": "Statement",
25839
+ "valueType": "string",
25840
+ "inputType": "textarea"
26086
25841
  },
26087
25842
  {
26088
- "id": "task-eb-props",
26089
- "kind": "widget",
26090
- "widgetType": "entity-properties",
26091
- "pos": {
26092
- "x": 0,
26093
- "y": 2,
26094
- "w": 5,
26095
- "h": 8
25843
+ "slug": "stance",
25844
+ "label": "Stance",
25845
+ "valueType": "string",
25846
+ "inputType": "select",
25847
+ "enumValues": [
25848
+ "proposed",
25849
+ "supported",
25850
+ "contested",
25851
+ "refuted",
25852
+ "superseded"
25853
+ ],
25854
+ "constraints": {
25855
+ "defaultValue": "proposed"
26096
25856
  }
26097
25857
  },
26098
25858
  {
26099
- "id": "task-eb-content",
26100
- "kind": "widget",
26101
- "widgetType": "entity-content",
26102
- "pos": {
26103
- "x": 5,
26104
- "y": 2,
26105
- "w": 7,
26106
- "h": 8
26107
- }
25859
+ "slug": "confidence",
25860
+ "label": "Confidence",
25861
+ "valueType": "string",
25862
+ "inputType": "select",
25863
+ "enumValues": [
25864
+ "low",
25865
+ "medium",
25866
+ "high"
25867
+ ]
25868
+ },
25869
+ {
25870
+ "slug": "reasoning",
25871
+ "label": "Reasoning",
25872
+ "valueType": "string",
25873
+ "inputType": "textarea"
26108
25874
  }
26109
25875
  ]
26110
25876
  },
26111
- "sprint": {
26112
- "blocks": [
25877
+ {
25878
+ "slug": "finding",
25879
+ "displayName": "Finding",
25880
+ "icon": "check-circle",
25881
+ "color": "#10B981",
25882
+ "description": "A validated fact \u2014 the thing established between the question, the sources, and the reasoning. Carries calibrated confidence and links to its evidence.",
25883
+ "properties": [
26113
25884
  {
26114
- "id": "sprint-eb-header",
26115
- "kind": "widget",
26116
- "widgetType": "entity-header",
26117
- "pos": {
26118
- "x": 0,
26119
- "y": 0,
26120
- "w": 12,
26121
- "h": 2
26122
- }
25885
+ "slug": "claim",
25886
+ "label": "Claim",
25887
+ "valueType": "string",
25888
+ "inputType": "textarea"
26123
25889
  },
26124
25890
  {
26125
- "id": "sprint-eb-props",
26126
- "kind": "widget",
26127
- "widgetType": "entity-properties",
26128
- "pos": {
26129
- "x": 0,
26130
- "y": 2,
26131
- "w": 4,
26132
- "h": 6
25891
+ "slug": "confidence",
25892
+ "label": "Confidence (0\u20131)",
25893
+ "valueType": "number",
25894
+ "inputType": "number",
25895
+ "constraints": {
25896
+ "min": 0,
25897
+ "max": 1
26133
25898
  }
26134
25899
  },
26135
25900
  {
26136
- "id": "sprint-eb-tasks",
26137
- "kind": "widget",
26138
- "widgetType": "entity-list",
26139
- "pos": {
26140
- "x": 4,
26141
- "y": 2,
26142
- "w": 8,
26143
- "h": 6
26144
- },
26145
- "config": {
26146
- "profileSlug": "task",
26147
- "title": "Sprint Tasks",
26148
- "limit": 10,
26149
- "variant": "compact"
25901
+ "slug": "evidenceSummary",
25902
+ "label": "Evidence summary",
25903
+ "valueType": "string",
25904
+ "inputType": "textarea"
25905
+ },
25906
+ {
25907
+ "slug": "status",
25908
+ "label": "Status",
25909
+ "valueType": "string",
25910
+ "inputType": "select",
25911
+ "enumValues": [
25912
+ "validated",
25913
+ "provisional",
25914
+ "retracted"
25915
+ ],
25916
+ "constraints": {
25917
+ "defaultValue": "provisional"
26150
25918
  }
26151
25919
  }
26152
25920
  ]
26153
25921
  }
26154
- },
25922
+ ],
25923
+ "views": [
25924
+ {
25925
+ "name": "Knowledge Map",
25926
+ "slug": "research-knowledge-map",
25927
+ "type": "graph",
25928
+ "scopeProfileSlugs": [
25929
+ "field",
25930
+ "concept",
25931
+ "finding"
25932
+ ],
25933
+ "description": "The cartography \u2014 fields and concepts, their overlaps and prerequisites, and the findings attached to them.",
25934
+ "defaultView": true,
25935
+ "config": {
25936
+ "layout": "force",
25937
+ "showRelations": true
25938
+ }
25939
+ },
25940
+ {
25941
+ "name": "Open Questions",
25942
+ "slug": "research-open-questions",
25943
+ "type": "list",
25944
+ "scopeProfileSlug": "question",
25945
+ "description": "Questions still open \u2014 the research backlog.",
25946
+ "config": {
25947
+ "filterBy": {
25948
+ "field": "questionStatus",
25949
+ "operator": "is",
25950
+ "value": "open"
25951
+ }
25952
+ }
25953
+ },
25954
+ {
25955
+ "name": "Sources",
25956
+ "slug": "research-sources",
25957
+ "type": "table",
25958
+ "scopeProfileSlug": "source",
25959
+ "description": "Every source consulted, ranked by credibility \u2014 including the ones that were considered and rejected.",
25960
+ "config": {
25961
+ "columns": [
25962
+ "title",
25963
+ "sourceType",
25964
+ "credibilityBand",
25965
+ "qualityScore",
25966
+ "status"
25967
+ ]
25968
+ }
25969
+ },
25970
+ {
25971
+ "name": "Hypotheses",
25972
+ "slug": "research-hypotheses",
25973
+ "type": "kanban",
25974
+ "scopeProfileSlug": "hypothesis",
25975
+ "groupBy": "stance",
25976
+ "description": "Candidate theories, grouped by where the evidence has left them.",
25977
+ "config": {
25978
+ "groupBy": "stance"
25979
+ }
25980
+ },
25981
+ {
25982
+ "name": "Findings",
25983
+ "slug": "research-findings",
25984
+ "type": "table",
25985
+ "scopeProfileSlug": "finding",
25986
+ "description": "What's been established, with its confidence.",
25987
+ "config": {
25988
+ "columns": [
25989
+ "title",
25990
+ "confidence",
25991
+ "status"
25992
+ ]
25993
+ }
25994
+ },
25995
+ {
25996
+ "name": "Research Log",
25997
+ "slug": "research-log",
25998
+ "type": "table",
25999
+ "scopeProfileSlug": "research",
26000
+ "description": "Every investigation and where it stands.",
26001
+ "config": {
26002
+ "columns": [
26003
+ "title",
26004
+ "researchStatus",
26005
+ "researchConfidence"
26006
+ ]
26007
+ }
26008
+ }
26009
+ ],
26010
+ "entityLinks": [
26011
+ {
26012
+ "sourceProfileSlug": "field",
26013
+ "targetProfileSlug": "field",
26014
+ "type": "overlaps_with",
26015
+ "label": "Overlaps with"
26016
+ },
26017
+ {
26018
+ "sourceProfileSlug": "concept",
26019
+ "targetProfileSlug": "field",
26020
+ "type": "part_of",
26021
+ "label": "Part of"
26022
+ },
26023
+ {
26024
+ "sourceProfileSlug": "concept",
26025
+ "targetProfileSlug": "concept",
26026
+ "type": "prerequisite_of",
26027
+ "label": "Prerequisite of"
26028
+ },
26029
+ {
26030
+ "sourceProfileSlug": "concept",
26031
+ "targetProfileSlug": "concept",
26032
+ "type": "relates_to",
26033
+ "label": "Relates to"
26034
+ },
26035
+ {
26036
+ "sourceProfileSlug": "research",
26037
+ "targetProfileSlug": "question",
26038
+ "type": "investigates",
26039
+ "label": "Investigates"
26040
+ },
26041
+ {
26042
+ "sourceProfileSlug": "hypothesis",
26043
+ "targetProfileSlug": "question",
26044
+ "type": "answers",
26045
+ "label": "Answers"
26046
+ },
26047
+ {
26048
+ "sourceProfileSlug": "research",
26049
+ "targetProfileSlug": "source",
26050
+ "type": "explored",
26051
+ "label": "Explored"
26052
+ },
26053
+ {
26054
+ "sourceProfileSlug": "research",
26055
+ "targetProfileSlug": "finding",
26056
+ "type": "concluded",
26057
+ "label": "Concluded"
26058
+ },
26059
+ {
26060
+ "sourceProfileSlug": "source",
26061
+ "targetProfileSlug": "hypothesis",
26062
+ "type": "supports",
26063
+ "label": "Supports"
26064
+ },
26065
+ {
26066
+ "sourceProfileSlug": "source",
26067
+ "targetProfileSlug": "hypothesis",
26068
+ "type": "contradicts",
26069
+ "label": "Contradicts"
26070
+ },
26071
+ {
26072
+ "sourceProfileSlug": "source",
26073
+ "targetProfileSlug": "source",
26074
+ "type": "cites",
26075
+ "label": "Cites"
26076
+ },
26077
+ {
26078
+ "sourceProfileSlug": "finding",
26079
+ "targetProfileSlug": "research",
26080
+ "type": "derived_from",
26081
+ "label": "Derived from"
26082
+ },
26083
+ {
26084
+ "sourceProfileSlug": "finding",
26085
+ "targetProfileSlug": "source",
26086
+ "type": "supported_by",
26087
+ "label": "Supported by"
26088
+ },
26089
+ {
26090
+ "sourceProfileSlug": "finding",
26091
+ "targetProfileSlug": "concept",
26092
+ "type": "about",
26093
+ "label": "About"
26094
+ }
26095
+ ],
26155
26096
  "playbooks": [
26156
26097
  {
26157
- "name": "Sprint Retrospective",
26158
- "goalTemplate": "Run a retrospective for {sprint} to review what went well, what didn't, and what to improve next sprint.",
26098
+ "name": "Research a Question",
26099
+ "description": "Investigate a question end-to-end \u2014 gather and rank sources (keeping the rejected ones), weigh hypotheses, emit findings with calibrated confidence, and map them onto the knowledge graph.",
26100
+ "goalTemplate": "Investigate the question {question} and record the WHOLE investigation, not just the answer. Steps: (1) Use the source-triage skill to gather sources widely via web search, classify each by type and credibility, and create a `source` entity for every one \u2014 including the ones you rejected, marked rejected with a reason (never silently drop a source). (2) Form the candidate answers as `hypothesis` entities and link each to the question; link every source that bears on a hypothesis with `supports` or `contradicts`. (3) Use the evidence-synthesis skill to weigh the supporting vs contradicting sources and emit `finding` entities with honestly calibrated confidence, each `supported_by` its sources and `derived_from` this research. (4) Use the concept-cartography skill to place the findings onto the knowledge map \u2014 resolve or create the `field`/`concept` entities and wire `about` / `part_of` / `overlaps_with` / `prerequisite_of` edges, deduping against what already exists. (5) Create the `research` entity that `investigates` the question and `explored` the sources, write its conclusion and confidence, and set the question's status to answered. Every write is proposal-gated and reviewable.",
26101
+ "subjectProfile": {
26102
+ "profileSlug": "question"
26103
+ },
26159
26104
  "params": [
26160
26105
  {
26161
- "name": "sprint",
26106
+ "name": "question",
26162
26107
  "type": "entity",
26163
- "label": "Sprint",
26108
+ "label": "Question",
26164
26109
  "required": true
26165
26110
  }
26166
- ]
26111
+ ],
26112
+ "executor": "is-agent",
26113
+ "grants": [
26114
+ "source-triage",
26115
+ "evidence-synthesis",
26116
+ "concept-cartography",
26117
+ "exa_search",
26118
+ "entity.create"
26119
+ ],
26120
+ "status": "active"
26121
+ }
26122
+ ],
26123
+ "actionPlacements": [
26124
+ {
26125
+ "profileSlug": "question",
26126
+ "surface": "entity-detail",
26127
+ "kind": "playbook",
26128
+ "ref": "Research a Question",
26129
+ "label": "Research this"
26130
+ }
26131
+ ],
26132
+ "integrations": [
26133
+ {
26134
+ "templateKey": "research-methods"
26135
+ },
26136
+ {
26137
+ "templateKey": "exa"
26167
26138
  }
26168
26139
  ],
26169
26140
  "onboarding": {
26170
- "goal": "Capture the user's goals, the projects in flight, the current sprint, and who's involved \u2014 so the workspace mirrors how their team actually plans and delivers.",
26171
- "framing": "Act as a sharp delivery lead / chief of staff. Tease out what outcomes matter this quarter, what's actively being worked, what's in the current cycle, and who owns what. Translate that into OKRs, projects, a sprint, and people.",
26141
+ "goal": "Seed the workspace with the first real questions worth researching and the fields they live in \u2014 so the agent has something concrete to investigate, not a blank graph.\n",
26142
+ "framing": `THE RESEARCH LEAD: Act as a sharp research lead who cares about the QUESTION
26143
+ being well-formed and the EVIDENCE being honest. A vague question ("learn
26144
+ about AI") produces vague research; push for a question with a real edge \u2014 one
26145
+ a good answer would actually change. And insist the work keeps its
26146
+ counter-evidence: research that only kept what agreed with it isn't research.
26147
+ `,
26172
26148
  "expertise": {
26173
26149
  "starters": [
26174
- `Don't collect a wishlist of goals \u2014 force ONE north-star metric and 2-3 key results that move it. Propose "the single number that means this quarter succeeded" first, then the handful of measurable KRs under it. Five objectives is zero objectives; a team that's aiming at everything is aiming at nothing.
26175
- `,
26176
- `Capture what's actually in flight and impose a WIP limit as you go. Ask "what's genuinely being worked THIS week" \u2014 not the backlog \u2014 and if it's more than the team can finish, that's the finding. Too many projects in progress means nothing ships; the map should make the overload visible.
26177
- `,
26178
- 'Every project and KR gets a named owner before anything else. Lead with "who owns this?" \u2014 a goal with no owner is a hope, and it will quietly slip. Capture the person on the project the moment you capture the project; ownerless work is the first thing to surface, not the last.\n'
26150
+ 'A researchable question names what would count as an answer. "Is X better than Y for Z?" beats "tell me about X" \u2014 the first has a shape the evidence can fill; the second is a topic, not a question.\n',
26151
+ "Name the field(s) the question lives in up front \u2014 even roughly. It's the first anchor on the map, and it's what lets the system later surface the neighbouring field you didn't think to look in.\n"
26179
26152
  ],
26180
26153
  "blindSpots": [
26181
- `"Everything is P1" is the prioritization failure that guarantees the wrong things ship. When every project is Critical, priority carries no information and the team defaults to whatever's loudest. Push back on the priority field \u2014 force a real ranking, because if you can't say what's LESS important, you haven't prioritized at all.
26182
- `,
26183
- `A goal with no owner is a hope, and hopes don't ship. Teams write beautiful OKRs with an empty owner field, and the KR that belongs to "the team" belongs to no one. Surface every ownerless objective, project, and KR \u2014 accountability is a name, not a shared intention.
26184
- `,
26185
- 'Too much work-in-progress is the silent throughput killer. Founders equate "many things started" with progress, but a dozen 60%-done projects deliver nothing while three finished ones deliver value. Watch the count of In-Progress items and flag when it exceeds what the team can actually close in a cycle.\n'
26186
- ],
26187
- "bar": `A great result is a workspace where the line from a single north-star metric down to the task in flight this week is unbroken: one clear objective with measurable KRs, every project and goal owned by a named person, a real priority ranking (not all-P1), and a WIP that matches capacity. You can answer "are we on track, who owns the thing that's slipping, and what should we STOP to ship what matters?" in one look.
26188
- `
26154
+ "The most valuable sources are often the ones that DISAGREE. If the founder only wants confirmation, say plainly that a one-sided answer is a weaker answer \u2014 the method keeps both sides on purpose.\n",
26155
+ '"I already know the answer" is where research quietly stops being research. If the conclusion is decided before the sources are gathered, flag it \u2014 the point is to be able to be wrong.\n'
26156
+ ]
26189
26157
  },
26190
26158
  "collect": [
26191
26159
  {
26192
- "profileSlug": "okr",
26193
- "what": "The goals / OKRs that define success this quarter",
26160
+ "profileSlug": "question",
26161
+ "what": "The first real questions worth investigating \u2014 each with a genuine edge, not a topic.",
26194
26162
  "cardinality": "few",
26195
26163
  "keyFields": [
26196
- "title",
26197
- "okr-quarter",
26198
- "okr-owner",
26199
- "kr1-label"
26164
+ "questionStatus"
26200
26165
  ]
26201
26166
  },
26202
26167
  {
26203
- "profileSlug": "project",
26204
- "what": "The projects actively in flight and their priority",
26205
- "cardinality": "several",
26168
+ "profileSlug": "field",
26169
+ "what": "The fields these questions live in \u2014 the first anchors on the knowledge map.",
26170
+ "cardinality": "few",
26206
26171
  "keyFields": [
26207
- "title",
26208
- "project-status",
26209
- "project-priority",
26210
- "project-linked-okr"
26172
+ "description"
26211
26173
  ]
26174
+ }
26175
+ ],
26176
+ "openingQuestions": [
26177
+ "What's a question you actually want a well-evidenced answer to \u2014 one where a good answer would change what you do?",
26178
+ "Which field(s) does it sit in \u2014 and is there a neighbouring field it might borrow from?",
26179
+ "What would count as a convincing answer, and what would change your mind?"
26180
+ ],
26181
+ "doneWhen": "At least one well-formed question captured with its field(s) anchored on the map, ready for the Research a Question playbook to run against.\n"
26182
+ },
26183
+ "app": {
26184
+ "kind": "stored",
26185
+ "cellKey": "entity-detail"
26186
+ },
26187
+ "layout": {
26188
+ "defaultView": "Knowledge Map",
26189
+ "defaultApp": null,
26190
+ "pinnedApps": [
26191
+ "dashboard",
26192
+ "data",
26193
+ "chat"
26194
+ ],
26195
+ "sidebarItems": [
26196
+ {
26197
+ "kind": "view",
26198
+ "viewName": "Knowledge Map",
26199
+ "label": "Map",
26200
+ "icon": "layers"
26212
26201
  },
26213
26202
  {
26214
- "profileSlug": "sprint",
26215
- "what": "The current cycle / sprint and its goal",
26216
- "cardinality": "one",
26217
- "keyFields": [
26203
+ "kind": "view",
26204
+ "viewName": "Open Questions",
26205
+ "label": "Questions",
26206
+ "icon": "help-circle"
26207
+ },
26208
+ {
26209
+ "kind": "view",
26210
+ "viewName": "Sources",
26211
+ "label": "Sources",
26212
+ "icon": "file-text"
26213
+ },
26214
+ {
26215
+ "kind": "view",
26216
+ "viewName": "Findings",
26217
+ "label": "Findings",
26218
+ "icon": "check-circle"
26219
+ },
26220
+ {
26221
+ "kind": "app",
26222
+ "appId": "data",
26223
+ "label": "Data",
26224
+ "icon": "database"
26225
+ }
26226
+ ]
26227
+ },
26228
+ "bento": {
26229
+ "viewName": "Research Home",
26230
+ "blocks": [
26231
+ {
26232
+ "kind": "view",
26233
+ "viewName": "Knowledge Map",
26234
+ "pos": {
26235
+ "x": 0,
26236
+ "y": 0,
26237
+ "w": 8,
26238
+ "h": 6
26239
+ }
26240
+ },
26241
+ {
26242
+ "kind": "view",
26243
+ "viewName": "Open Questions",
26244
+ "pos": {
26245
+ "x": 8,
26246
+ "y": 0,
26247
+ "w": 4,
26248
+ "h": 3
26249
+ }
26250
+ },
26251
+ {
26252
+ "kind": "view",
26253
+ "viewName": "Findings",
26254
+ "pos": {
26255
+ "x": 8,
26256
+ "y": 3,
26257
+ "w": 4,
26258
+ "h": 3
26259
+ }
26260
+ }
26261
+ ]
26262
+ }
26263
+ },
26264
+ "research-decision": {
26265
+ "meta": {
26266
+ "slug": "research-decision",
26267
+ "domain": "knowledge",
26268
+ "name": "Decision Analysis",
26269
+ "description": "Turn an open question into a decision \u2014 options weighed with evidence, and the roads-not-taken preserved with the reasons they lost. Composes onto the Research substrate.",
26270
+ "icon": "scale",
26271
+ "color": "#F59E0B",
26272
+ "tags": [
26273
+ "research",
26274
+ "decision",
26275
+ "ibis",
26276
+ "analysis",
26277
+ "evidence"
26278
+ ],
26279
+ "isPublic": true
26280
+ },
26281
+ "workspace": {
26282
+ "name": "Research",
26283
+ "description": "Adds the IBIS decision-analysis method to the Research substrate \u2014 weigh options with evidence and record the decision, not just the winner.",
26284
+ "subtype": "research-base"
26285
+ },
26286
+ "dependencies": [
26287
+ {
26288
+ "slug": "research-base",
26289
+ "relation": "compose",
26290
+ "reason": "Decision Analysis is a research method \u2014 it needs the Research substrate (question / source / hypothesis / finding) to work over."
26291
+ }
26292
+ ],
26293
+ "profiles": [
26294
+ {
26295
+ "slug": "question",
26296
+ "displayName": "Question",
26297
+ "icon": "help-circle",
26298
+ "color": "blue",
26299
+ "description": "The open question being decided.",
26300
+ "properties": [
26301
+ {
26302
+ "slug": "questionStatus",
26303
+ "label": "Status",
26304
+ "valueType": "string",
26305
+ "inputType": "select",
26306
+ "enumValues": [
26307
+ "open",
26308
+ "exploring",
26309
+ "answered",
26310
+ "abandoned"
26311
+ ],
26312
+ "constraints": {
26313
+ "defaultValue": "open"
26314
+ }
26315
+ }
26316
+ ]
26317
+ },
26318
+ {
26319
+ "slug": "hypothesis",
26320
+ "displayName": "Option",
26321
+ "icon": "git-branch",
26322
+ "color": "violet",
26323
+ "description": "A candidate option under consideration \u2014 argued for and against by sources.",
26324
+ "properties": [
26325
+ {
26326
+ "slug": "stance",
26327
+ "label": "Stance",
26328
+ "valueType": "string",
26329
+ "inputType": "select",
26330
+ "enumValues": [
26331
+ "proposed",
26332
+ "supported",
26333
+ "contested",
26334
+ "refuted",
26335
+ "superseded"
26336
+ ],
26337
+ "constraints": {
26338
+ "defaultValue": "proposed"
26339
+ }
26340
+ }
26341
+ ]
26342
+ },
26343
+ {
26344
+ "slug": "decision",
26345
+ "displayName": "Decision",
26346
+ "icon": "scale",
26347
+ "color": "amber",
26348
+ "description": "A resolved decision \u2014 the recommendation, why it won, and the alternatives that lost (and why).",
26349
+ "properties": [
26350
+ {
26351
+ "slug": "summary",
26352
+ "label": "Summary",
26353
+ "valueType": "string",
26354
+ "inputType": "text"
26355
+ },
26356
+ {
26357
+ "slug": "rationale",
26358
+ "label": "Rationale",
26359
+ "valueType": "string",
26360
+ "inputType": "textarea"
26361
+ },
26362
+ {
26363
+ "slug": "alternatives",
26364
+ "label": "Alternatives considered",
26365
+ "valueType": "string",
26366
+ "inputType": "textarea"
26367
+ },
26368
+ {
26369
+ "slug": "decisionStatus",
26370
+ "label": "Status",
26371
+ "valueType": "string",
26372
+ "inputType": "select",
26373
+ "enumValues": [
26374
+ "proposed",
26375
+ "accepted",
26376
+ "superseded",
26377
+ "rejected"
26378
+ ],
26379
+ "constraints": {
26380
+ "defaultValue": "proposed"
26381
+ }
26382
+ }
26383
+ ]
26384
+ }
26385
+ ],
26386
+ "views": [
26387
+ {
26388
+ "name": "Decisions",
26389
+ "slug": "research-decisions",
26390
+ "type": "table",
26391
+ "scopeProfileSlug": "decision",
26392
+ "description": "Every decision reached, its recommendation, and where it stands.",
26393
+ "config": {
26394
+ "columns": [
26218
26395
  "title",
26219
- "sprint-goal",
26220
- "sprint-start",
26221
- "sprint-end"
26222
- ]
26223
- },
26224
- {
26225
- "profileSlug": "person",
26226
- "what": "The key people on the team and their roles",
26227
- "cardinality": "several",
26228
- "keyFields": [
26229
- "name",
26230
- "person-role",
26231
- "person-email"
26396
+ "summary",
26397
+ "decisionStatus"
26232
26398
  ]
26233
26399
  }
26234
- ],
26235
- "openingQuestions": [
26236
- "What are the big outcomes you're trying to hit this quarter?",
26237
- "What projects are actively in flight right now, and which matter most?",
26238
- "Who's on the team, and what does each person own?"
26239
- ],
26240
- "doneWhen": "This quarter's goals exist, active projects are captured with priority, a current sprint is defined, and the core team is on the board."
26241
- }
26400
+ }
26401
+ ],
26402
+ "entityLinks": [
26403
+ {
26404
+ "sourceProfileSlug": "decision",
26405
+ "targetProfileSlug": "question",
26406
+ "type": "resolves",
26407
+ "label": "Resolves"
26408
+ },
26409
+ {
26410
+ "sourceProfileSlug": "hypothesis",
26411
+ "targetProfileSlug": "decision",
26412
+ "type": "considered_in",
26413
+ "label": "Considered in"
26414
+ }
26415
+ ],
26416
+ "playbooks": [
26417
+ {
26418
+ "name": "Decision Analysis",
26419
+ "description": "Structure an open question as a decision via IBIS \u2014 enumerate the options, argue each with evidence (keeping the rejected sources), weigh against explicit criteria, and record the decision with its roads-not-taken.",
26420
+ "goalTemplate": "Analyze the question {question} as a DECISION and record the reasoning, not just the verdict, using the ibis-decision-analysis skill. Steps: (1) State the issue sharply so the options are genuinely mutually exclusive. (2) Enumerate the real options \u2014 including the status-quo \u2014 as `hypothesis` entities linked to the question, and to the resulting decision via `considered_in`. (3) For each option, gather the sources that `supports` and those that `contradicts` it (use source gathering; KEEP the rejected sources with a reason \u2014 never drop the counter-evidence). (4) Weigh the options against explicit, named criteria (cost, reversibility, risk, time, evidence strength). (5) Record the recommendation as a `decision` entity that `resolves` the question \u2014 its rationale explains why it won, and its `alternatives` field preserves the options that lost and WHY. (6) Note what evidence would change the decision. Every write is proposal-gated.",
26421
+ "subjectProfile": {
26422
+ "profileSlug": "question"
26423
+ },
26424
+ "params": [
26425
+ {
26426
+ "name": "question",
26427
+ "type": "entity",
26428
+ "label": "Question",
26429
+ "required": true
26430
+ }
26431
+ ],
26432
+ "executor": "is-agent",
26433
+ "grants": [
26434
+ "ibis-decision-analysis",
26435
+ "source-triage",
26436
+ "exa_search",
26437
+ "entity.create"
26438
+ ],
26439
+ "status": "active"
26440
+ }
26441
+ ],
26442
+ "actionPlacements": [
26443
+ {
26444
+ "profileSlug": "question",
26445
+ "surface": "entity-detail",
26446
+ "kind": "playbook",
26447
+ "ref": "Decision Analysis",
26448
+ "label": "Analyze as decision"
26449
+ }
26450
+ ],
26451
+ "integrations": [
26452
+ {
26453
+ "templateKey": "research-methods"
26454
+ },
26455
+ {
26456
+ "templateKey": "exa"
26457
+ }
26458
+ ]
26242
26459
  },
26243
26460
  "social": {
26244
26461
  "meta": {
26245
26462
  "slug": "social",
26463
+ "domain": "content",
26246
26464
  "name": "Social",
26247
26465
  "description": "Plan, schedule, and publish across your channels \u2014 then track how each post performs. Channels, posts, schedules, and engagement signals, all connected.",
26248
26466
  "icon": "share-2",
@@ -26255,6 +26473,14 @@ var DATA = {
26255
26473
  ],
26256
26474
  "isPublic": true
26257
26475
  },
26476
+ "dependencies": [
26477
+ {
26478
+ "slug": "content-os",
26479
+ "kind": "workspace",
26480
+ "relation": "require",
26481
+ "reason": "Reuses Content OS's shared platform (publishing-account) vocabulary."
26482
+ }
26483
+ ],
26258
26484
  "workspace": {
26259
26485
  "name": "Social",
26260
26486
  "description": "The distribution layer \u2014 the channels you publish on, the posts and schedules that pace them, and the engagement signals that tell you what's working.",
@@ -26273,59 +26499,110 @@ var DATA = {
26273
26499
  },
26274
26500
  "profiles": [
26275
26501
  {
26276
- "slug": "channel",
26277
- "displayName": "Channel",
26278
- "icon": "radio",
26279
- "color": "#1D9BF0",
26280
- "description": "A social account you publish on \u2014 a platform, a handle, and its audience.",
26502
+ "slug": "platform",
26503
+ "displayName": "Platform",
26504
+ "icon": "share-2",
26505
+ "color": "#06B6D4",
26506
+ "description": "A social account, newsletter publication, or podcast channel. Each platform has its own audience metrics and publishing rhythm.",
26507
+ "scope": "shared",
26281
26508
  "properties": [
26282
26509
  {
26283
- "slug": "platform",
26284
- "label": "Platform",
26510
+ "slug": "platform-type",
26511
+ "label": "Type",
26285
26512
  "valueType": "string",
26286
26513
  "inputType": "select",
26287
26514
  "enumValues": [
26288
- "x",
26289
- "linkedin",
26290
- "instagram",
26291
- "tiktok",
26292
- "youtube",
26293
- "facebook",
26294
- "threads",
26295
- "other"
26515
+ "LinkedIn",
26516
+ "Instagram",
26517
+ "TikTok",
26518
+ "YouTube",
26519
+ "Twitter / X",
26520
+ "Threads",
26521
+ "Bluesky",
26522
+ "Newsletter",
26523
+ "Podcast",
26524
+ "Blog / Website",
26525
+ "Other"
26296
26526
  ]
26297
26527
  },
26298
26528
  {
26299
26529
  "slug": "handle",
26300
26530
  "label": "Handle",
26301
26531
  "valueType": "string",
26302
- "inputType": "text"
26532
+ "inputType": "text",
26533
+ "placeholder": "@username"
26303
26534
  },
26304
26535
  {
26305
- "slug": "channel-url",
26306
- "label": "URL",
26536
+ "slug": "platform-status",
26537
+ "label": "Status",
26307
26538
  "valueType": "string",
26308
- "inputType": "url"
26539
+ "inputType": "select",
26540
+ "enumValues": [
26541
+ "Active",
26542
+ "Building",
26543
+ "Maintenance Mode",
26544
+ "Inactive"
26545
+ ]
26546
+ },
26547
+ {
26548
+ "slug": "platform-url",
26549
+ "label": "Profile URL",
26550
+ "valueType": "string",
26551
+ "inputType": "text",
26552
+ "placeholder": "https://...",
26553
+ "constraints": {
26554
+ "format": "url"
26555
+ }
26309
26556
  },
26310
26557
  {
26311
26558
  "slug": "follower-count",
26312
- "label": "Followers",
26559
+ "label": "Follower / Subscriber Count",
26313
26560
  "valueType": "number",
26314
26561
  "inputType": "number"
26315
26562
  },
26316
26563
  {
26317
- "slug": "channel-status",
26318
- "label": "Status",
26564
+ "slug": "follower-target",
26565
+ "label": "Target Count",
26566
+ "valueType": "number",
26567
+ "inputType": "number"
26568
+ },
26569
+ {
26570
+ "slug": "avg-engagement-rate",
26571
+ "label": "Avg Engagement Rate (%)",
26572
+ "valueType": "number",
26573
+ "inputType": "number"
26574
+ },
26575
+ {
26576
+ "slug": "platform-posting-freq",
26577
+ "label": "Posting Frequency",
26319
26578
  "valueType": "string",
26320
26579
  "inputType": "select",
26321
26580
  "enumValues": [
26322
- "active",
26323
- "paused",
26324
- "archived"
26325
- ],
26326
- "constraints": {
26327
- "defaultValue": "active"
26328
- }
26581
+ "Daily",
26582
+ "3x / week",
26583
+ "2x / week",
26584
+ "Weekly",
26585
+ "Bi-weekly",
26586
+ "Monthly",
26587
+ "As Needed"
26588
+ ]
26589
+ },
26590
+ {
26591
+ "slug": "last-post-date",
26592
+ "label": "Last Post Date",
26593
+ "valueType": "date"
26594
+ },
26595
+ {
26596
+ "slug": "platform-notes",
26597
+ "label": "Notes",
26598
+ "valueType": "string",
26599
+ "inputType": "text",
26600
+ "placeholder": "What works here? Tone, format, best times..."
26601
+ },
26602
+ {
26603
+ "slug": "platform-tags",
26604
+ "label": "Tags",
26605
+ "valueType": "array"
26329
26606
  }
26330
26607
  ]
26331
26608
  },
@@ -26352,10 +26629,10 @@ var DATA = {
26352
26629
  }
26353
26630
  },
26354
26631
  {
26355
- "slug": "post-channel",
26356
- "label": "Channel",
26632
+ "slug": "post-platform",
26633
+ "label": "Platform",
26357
26634
  "valueType": "entity_id",
26358
- "targetProfileSlug": "channel",
26635
+ "targetProfileSlug": "platform",
26359
26636
  "inputType": "entity_select"
26360
26637
  },
26361
26638
  {
@@ -26398,10 +26675,10 @@ var DATA = {
26398
26675
  "description": "A recurring cadence for a channel \u2014 the slot pattern that keeps posting consistent.",
26399
26676
  "properties": [
26400
26677
  {
26401
- "slug": "schedule-channel",
26402
- "label": "Channel",
26678
+ "slug": "schedule-platform",
26679
+ "label": "Platform",
26403
26680
  "valueType": "entity_id",
26404
- "targetProfileSlug": "channel",
26681
+ "targetProfileSlug": "platform",
26405
26682
  "inputType": "entity_select"
26406
26683
  },
26407
26684
  {
@@ -26439,10 +26716,10 @@ var DATA = {
26439
26716
  "description": "A performance reading for a channel over a period \u2014 reach, impressions, and the reactions that came back.",
26440
26717
  "properties": [
26441
26718
  {
26442
- "slug": "signal-channel",
26443
- "label": "Channel",
26719
+ "slug": "signal-platform",
26720
+ "label": "Platform",
26444
26721
  "valueType": "entity_id",
26445
- "targetProfileSlug": "channel",
26722
+ "targetProfileSlug": "platform",
26446
26723
  "inputType": "entity_select"
26447
26724
  },
26448
26725
  {
@@ -26506,11 +26783,11 @@ var DATA = {
26506
26783
  "description": "Posts on a board by status \u2014 draft to published."
26507
26784
  },
26508
26785
  {
26509
- "name": "Channels",
26510
- "slug": "channels",
26786
+ "name": "Platforms",
26787
+ "slug": "platforms",
26511
26788
  "type": "table",
26512
- "scopeProfileSlug": "channel",
26513
- "description": "The channels you publish on, with platform, handle, and audience."
26789
+ "scopeProfileSlug": "platform",
26790
+ "description": "The platforms you publish on, with type, handle, and audience."
26514
26791
  },
26515
26792
  {
26516
26793
  "name": "Signals",
@@ -26525,21 +26802,21 @@ var DATA = {
26525
26802
  "framing": 'THE SOCIAL LEAD: Act as a sharp distribution lead. Anchor every post to a real Content asset or a Marketing brief \u2014 social is the distribution arm, not a separate content factory. Push for one channel done genuinely well over spraying thin across five. Refuse "we post everywhere" \u2014 ask which channel actually earns attention, and what the real cadence is.\n',
26526
26803
  "collect": [
26527
26804
  {
26528
- "profileSlug": "channel",
26529
- "what": "The channels you actually publish on \u2014 one per real account, with its platform and handle.",
26805
+ "profileSlug": "platform",
26806
+ "what": "The platforms you actually publish on \u2014 one per real account, with its type and handle.",
26530
26807
  "cardinality": "few",
26531
26808
  "keyFields": [
26532
- "platform",
26809
+ "platform-type",
26533
26810
  "handle"
26534
26811
  ]
26535
26812
  },
26536
26813
  {
26537
26814
  "profileSlug": "social-post",
26538
- "what": "The posts in motion \u2014 drafts, scheduled, and recently published \u2014 each tied to its channel.",
26815
+ "what": "The posts in motion \u2014 drafts, scheduled, and recently published \u2014 each tied to its platform.",
26539
26816
  "cardinality": "several",
26540
26817
  "keyFields": [
26541
26818
  "post-status",
26542
- "post-channel"
26819
+ "post-platform"
26543
26820
  ]
26544
26821
  }
26545
26822
  ],
@@ -26570,8 +26847,8 @@ var DATA = {
26570
26847
  },
26571
26848
  {
26572
26849
  "kind": "view",
26573
- "viewName": "Channels",
26574
- "label": "Channels",
26850
+ "viewName": "Platforms",
26851
+ "label": "Platforms",
26575
26852
  "icon": "radio"
26576
26853
  },
26577
26854
  {
@@ -26587,7 +26864,7 @@ var DATA = {
26587
26864
  "blocks": [
26588
26865
  {
26589
26866
  "kind": "view",
26590
- "viewName": "Channels",
26867
+ "viewName": "Platforms",
26591
26868
  "pos": {
26592
26869
  "x": 0,
26593
26870
  "y": 0,
@@ -26611,6 +26888,7 @@ var DATA = {
26611
26888
  "the-arch": {
26612
26889
  "meta": {
26613
26890
  "slug": "the-arch",
26891
+ "domain": "company",
26614
26892
  "name": "The Arch",
26615
26893
  "description": "The complete private company brain \u2014 the whole Enterprise OS plus the grant pipeline, the web3 ecosystem overlay, and the dev dashboard.",
26616
26894
  "icon": "landmark",
@@ -26746,6 +27024,11 @@ var DATA = {
26746
27024
  }
26747
27025
  }
26748
27026
  ],
27027
+ "integrations": [
27028
+ {
27029
+ "templateKey": "client-comms-report"
27030
+ }
27031
+ ],
26749
27032
  "onboarding": {
26750
27033
  "goal": "Name the cross-workspace initiatives that span the operating system and its private flagships \u2014 the few big things in flight that touch more than one lens \u2014 so The Arch is a real command layer, not just an aggregate of apps.\n",
26751
27034
  "framing": "THE FOUNDER'S COMMAND LAYER: Act from the seat above every lens. The whole\ncompany brain is installed \u2014 operating core plus the private grant, web3, and\ndev flagships. Your job is to surface the handful of initiatives that cut\nacross them and give each a stage, a lead, and a priority.\n",
@@ -26855,6 +27138,7 @@ function rowToRemoteEntry(row, isPrivate) {
26855
27138
  name: row.displayName,
26856
27139
  description: row.description ?? void 0,
26857
27140
  category: row.category,
27141
+ domain: row.domain ?? void 0,
26858
27142
  tags: row.tags ?? [],
26859
27143
  icon: row.icon ?? null,
26860
27144
  isPrivate
@@ -26884,10 +27168,12 @@ function bundledToEntry(tpl) {
26884
27168
  slug: tpl.meta.slug,
26885
27169
  name: tpl.meta.name,
26886
27170
  description: tpl.meta.description,
26887
- // Every bundled template is a full workspace — the CP calls this category
26888
- // "workspace" (PACKAGE_TYPES). Finer display grouping is derived from `tags`
26889
- // by the consumer (browser `categoryFor`), not baked in here.
27171
+ // `category` is the PACKAGE TYPE — every bundled template is a full
27172
+ // workspace (PACKAGE_TYPES). Human display grouping is the SEPARATE
27173
+ // authored `domain` field (see ./domains.ts), read straight from meta —
27174
+ // not re-derived from tags by each consumer, which is what drifted before.
26890
27175
  category: "workspace",
27176
+ domain: tpl.meta.domain,
26891
27177
  tags: tpl.meta.tags ?? [],
26892
27178
  icon: tpl.meta.icon,
26893
27179
  isPrivate: tpl.meta.isPublic === false,
@@ -26901,6 +27187,7 @@ function remoteToEntry(row) {
26901
27187
  name: row.name,
26902
27188
  description: row.description,
26903
27189
  category: row.category,
27190
+ domain: row.domain,
26904
27191
  tags: row.tags ?? [],
26905
27192
  icon: row.icon ?? null,
26906
27193
  isPrivate: row.isPrivate ?? false,
@@ -27212,6 +27499,402 @@ function formatConceptViolations(violations) {
27212
27499
  return violations.map((v) => ` \u2022 [${v.rule}] ${v.message}`).join("\n");
27213
27500
  }
27214
27501
 
27502
+ // src/domains.ts
27503
+ var OTHER_DOMAIN_ID = "other";
27504
+ var OTHER_DOMAIN_LABEL = "More";
27505
+ var TEMPLATE_DOMAINS = [
27506
+ { id: "strategy", label: "Strategy & Market" },
27507
+ { id: "revenue", label: "Sales & Marketing" },
27508
+ { id: "content", label: "Content & Social" },
27509
+ { id: "company", label: "Company & Operations" },
27510
+ { id: "build", label: "Build & Operate" },
27511
+ { id: "knowledge", label: "Knowledge & Research" }
27512
+ ];
27513
+ var KNOWN = new Map(
27514
+ TEMPLATE_DOMAINS.map((d, i) => [d.id, { label: d.label, order: i }])
27515
+ );
27516
+ function isKnownDomain(id) {
27517
+ return id != null && KNOWN.has(id);
27518
+ }
27519
+ function domainLabel(id) {
27520
+ if (!id) return OTHER_DOMAIN_LABEL;
27521
+ const known = KNOWN.get(id);
27522
+ if (known) return known.label;
27523
+ return id.replace(/[-_]/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
27524
+ }
27525
+ function groupByDomain(items, domainOf) {
27526
+ const buckets = /* @__PURE__ */ new Map();
27527
+ for (const item of items) {
27528
+ const id = domainOf(item) || OTHER_DOMAIN_ID;
27529
+ const bucket = buckets.get(id);
27530
+ if (bucket) bucket.push(item);
27531
+ else buckets.set(id, [item]);
27532
+ }
27533
+ const rank = (id) => {
27534
+ if (id === OTHER_DOMAIN_ID) return Number.MAX_SAFE_INTEGER;
27535
+ const known = KNOWN.get(id);
27536
+ return known ? known.order : 1e6;
27537
+ };
27538
+ return [...buckets.entries()].sort(([a], [b]) => {
27539
+ const ra = rank(a);
27540
+ const rb = rank(b);
27541
+ if (ra !== rb) return ra - rb;
27542
+ return a < b ? -1 : a > b ? 1 : 0;
27543
+ }).map(([id, groupItems]) => ({
27544
+ id,
27545
+ label: id === OTHER_DOMAIN_ID ? OTHER_DOMAIN_LABEL : domainLabel(id),
27546
+ items: groupItems
27547
+ }));
27548
+ }
27549
+
27550
+ // src/validate.ts
27551
+ var REQUIRED_META_FIELDS = [
27552
+ "slug",
27553
+ "name",
27554
+ "description",
27555
+ "icon",
27556
+ "color"
27557
+ ];
27558
+ var REQUIRED_WORKSPACE_FIELDS = ["name", "description"];
27559
+ var SCOPE_EXEMPT = /* @__PURE__ */ new Set(["whiteboard", "mindmap", "bento"]);
27560
+ var SYSTEM_PROFILES = /* @__PURE__ */ new Set([
27561
+ // Core capture hierarchy
27562
+ "note",
27563
+ "task",
27564
+ "event",
27565
+ "bookmark",
27566
+ "website",
27567
+ "article",
27568
+ // People / orgs / CRM
27569
+ "person",
27570
+ "contact",
27571
+ "company",
27572
+ "deal",
27573
+ // Files + programmatic kinds
27574
+ "file",
27575
+ "anchor",
27576
+ "signal_item",
27577
+ // Knowledge-work flow
27578
+ "decision",
27579
+ "question",
27580
+ "research",
27581
+ "knowledge",
27582
+ "user_observation"
27583
+ ]);
27584
+ function isPodWideProfile(p) {
27585
+ return String(p.scope || "").toLowerCase() === "shared";
27586
+ }
27587
+ function collectBaseProfileSlugs(data, resolveDep, seen = /* @__PURE__ */ new Set()) {
27588
+ const out = /* @__PURE__ */ new Set();
27589
+ for (const dep of data.dependencies || []) {
27590
+ if (dep.relation !== "compose" && dep.relation !== "require") continue;
27591
+ if (seen.has(dep.slug)) continue;
27592
+ seen.add(dep.slug);
27593
+ const base = resolveDep(dep.slug);
27594
+ if (!base) continue;
27595
+ const podWideOnly = dep.relation === "require";
27596
+ for (const p of base.profiles || []) {
27597
+ if (podWideOnly && !isPodWideProfile(p)) continue;
27598
+ out.add(p.slug);
27599
+ }
27600
+ for (const s of collectBaseProfileSlugs(base, resolveDep, seen)) out.add(s);
27601
+ }
27602
+ return out;
27603
+ }
27604
+ function collectProfileSlugRefs(node, path, out) {
27605
+ if (node == null || typeof node !== "object") return;
27606
+ if (Array.isArray(node)) {
27607
+ node.forEach((v, i) => collectProfileSlugRefs(v, `${path}[${i}]`, out));
27608
+ return;
27609
+ }
27610
+ for (const [k, v] of Object.entries(node)) {
27611
+ if (k === "profileSlug" && typeof v === "string" && !v.includes("{{")) {
27612
+ out.push({ where: `${path}.profileSlug`, slug: v });
27613
+ } else {
27614
+ collectProfileSlugRefs(v, `${path}.${k}`, out);
27615
+ }
27616
+ }
27617
+ }
27618
+ function resolveDepFrom(opts) {
27619
+ if (opts.resolveDep) return opts.resolveDep;
27620
+ if (opts.corpus) {
27621
+ const bySlug = /* @__PURE__ */ new Map();
27622
+ for (const t of opts.corpus) {
27623
+ const s = t.meta?.slug;
27624
+ if (s) bySlug.set(s, t);
27625
+ }
27626
+ return (slug) => bySlug.get(slug);
27627
+ }
27628
+ return () => void 0;
27629
+ }
27630
+ function validateTemplate(tpl, opts = {}) {
27631
+ const errors = [];
27632
+ const add = (rule, path, message) => errors.push({ rule, path, message });
27633
+ if (!tpl.meta) add("meta-required", "meta", "Missing required field: meta");
27634
+ else {
27635
+ for (const f of REQUIRED_META_FIELDS) {
27636
+ if (!tpl.meta[f]) add("meta-field-required", `meta.${f}`, `meta.${f} is required`);
27637
+ }
27638
+ }
27639
+ if (!tpl.workspace)
27640
+ add("workspace-required", "workspace", "Missing required field: workspace");
27641
+ else {
27642
+ for (const f of REQUIRED_WORKSPACE_FIELDS) {
27643
+ if (!tpl.workspace[f])
27644
+ add("workspace-field-required", `workspace.${f}`, `workspace.${f} is required`);
27645
+ }
27646
+ }
27647
+ if (!tpl.profiles || tpl.profiles.length === 0) {
27648
+ add("profiles-required", "profiles", "At least one profile is required");
27649
+ }
27650
+ const baseProfileSlugs = collectBaseProfileSlugs(tpl, resolveDepFrom(opts));
27651
+ const slugs = new Set((tpl.profiles || []).map((p) => p.slug));
27652
+ const known = (s) => slugs.has(s) || SYSTEM_PROFILES.has(s) || baseProfileSlugs.has(s);
27653
+ for (const v of tpl.views || []) {
27654
+ const type = String(v.type || "").toLowerCase();
27655
+ const scoped = v.scopeProfileSlug || v.scopeProfileSlugs && v.scopeProfileSlugs.length;
27656
+ if (!SCOPE_EXEMPT.has(type) && !scoped) {
27657
+ add(
27658
+ "view-missing-scope",
27659
+ `views."${v.name}"`,
27660
+ `view "${v.name}" (${type}) needs scopeProfileSlug(s) \u2014 structured views require a scope`
27661
+ );
27662
+ }
27663
+ if (v.scopeProfileSlug && !known(v.scopeProfileSlug))
27664
+ add(
27665
+ "view-scope-unknown",
27666
+ `views."${v.name}".scopeProfileSlug`,
27667
+ `view "${v.name}" scopes unknown profile "${v.scopeProfileSlug}"`
27668
+ );
27669
+ for (const s of v.scopeProfileSlugs || [])
27670
+ if (!known(s))
27671
+ add(
27672
+ "view-scope-unknown",
27673
+ `views."${v.name}".scopeProfileSlugs`,
27674
+ `view "${v.name}" scopes unknown profile "${s}"`
27675
+ );
27676
+ }
27677
+ for (const p of tpl.profiles || []) {
27678
+ for (const pr of p.properties || []) {
27679
+ if (pr.targetProfileSlug && !known(pr.targetProfileSlug)) {
27680
+ add(
27681
+ "property-target-unknown",
27682
+ `profiles.${p.slug}.${pr.slug}.targetProfileSlug`,
27683
+ `property ${p.slug}.${pr.slug} targets unknown profile "${pr.targetProfileSlug}"`
27684
+ );
27685
+ }
27686
+ }
27687
+ }
27688
+ for (const el of tpl.entityLinks || []) {
27689
+ if (!known(el.sourceProfileSlug))
27690
+ add(
27691
+ "entitylink-source-unknown",
27692
+ "entityLinks",
27693
+ `entityLink source "${el.sourceProfileSlug}" is unknown`
27694
+ );
27695
+ if (!known(el.targetProfileSlug))
27696
+ add(
27697
+ "entitylink-target-unknown",
27698
+ "entityLinks",
27699
+ `entityLink target "${el.targetProfileSlug}" is unknown`
27700
+ );
27701
+ if (typeof el.type !== "string" || !el.type) {
27702
+ add(
27703
+ "entitylink-missing-type",
27704
+ "entityLinks",
27705
+ `entityLink ${el.sourceProfileSlug}\u2192${el.targetProfileSlug} is missing its \`type\` (the predicate)`
27706
+ );
27707
+ }
27708
+ }
27709
+ for (const c of tpl.onboarding?.collect || []) {
27710
+ if (!known(c.profileSlug))
27711
+ add(
27712
+ "onboarding-ref-unknown",
27713
+ "onboarding.collect",
27714
+ `onboarding.collect references unknown profile "${c.profileSlug}"`
27715
+ );
27716
+ }
27717
+ for (const s of tpl.seedEntities || []) {
27718
+ if (!known(s.profileSlug))
27719
+ add(
27720
+ "seedentity-ref-unknown",
27721
+ "seedEntities",
27722
+ `seedEntity references unknown profile "${s.profileSlug}"`
27723
+ );
27724
+ }
27725
+ for (const a of tpl.automations || []) {
27726
+ const refs = [];
27727
+ collectProfileSlugRefs(a.triggerConfig, `automation "${a.name}".triggerConfig`, refs);
27728
+ collectProfileSlugRefs(a.flow, `automation "${a.name}".flow`, refs);
27729
+ for (const r of refs)
27730
+ if (!known(r.slug))
27731
+ add("automation-ref-unknown", r.where, `${r.where} references unknown profile "${r.slug}"`);
27732
+ }
27733
+ for (const pb of tpl.playbooks || []) {
27734
+ const ps = pb.subjectProfile?.profileSlug;
27735
+ if (ps && !known(ps))
27736
+ add(
27737
+ "playbook-ref-unknown",
27738
+ `playbooks."${pb.name}".subjectProfile`,
27739
+ `playbook "${pb.name}".subjectProfile references unknown profile "${ps}"`
27740
+ );
27741
+ }
27742
+ for (const ap of tpl.actionPlacements || []) {
27743
+ if (ap.profileSlug && !known(ap.profileSlug)) {
27744
+ add(
27745
+ "actionplacement-ref-unknown",
27746
+ "actionPlacements",
27747
+ `actionPlacement "${ap.label ?? ap.ref}" references unknown profile "${ap.profileSlug}"`
27748
+ );
27749
+ }
27750
+ }
27751
+ for (const si of tpl.layout?.sidebarItems || []) {
27752
+ if (si.profileSlug && !known(si.profileSlug)) {
27753
+ add(
27754
+ "sidebar-ref-unknown",
27755
+ "layout.sidebarItems",
27756
+ `layout.sidebarItems ("${si.label ?? si.profileSlug}") references unknown profile "${si.profileSlug}"`
27757
+ );
27758
+ }
27759
+ }
27760
+ for (const dt of tpl.displayTemplates || []) {
27761
+ if (dt.entityType && !known(dt.entityType)) {
27762
+ add(
27763
+ "displaytemplate-ref-unknown",
27764
+ `displayTemplates."${dt.name}".entityType`,
27765
+ `displayTemplate "${dt.name}" targets unknown profile "${dt.entityType}" (entityType)`
27766
+ );
27767
+ }
27768
+ }
27769
+ for (const key of Object.keys(tpl.profileEntityBentoTemplates || {})) {
27770
+ if (!known(key))
27771
+ add(
27772
+ "bentotemplate-ref-unknown",
27773
+ "profileEntityBentoTemplates",
27774
+ `profileEntityBentoTemplates has an entry for unknown profile "${key}"`
27775
+ );
27776
+ }
27777
+ const composeDeps = (tpl.dependencies || []).filter((d) => d.relation === "compose");
27778
+ for (const dep of composeDeps) {
27779
+ if (tpl.workspace?.visibility !== void 0) {
27780
+ add(
27781
+ "overlay-visibility",
27782
+ "workspace.visibility",
27783
+ `overlay (compose on "${dep.slug}") must OMIT workspace.visibility \u2014 it overwrites the base's on additive reconcile`
27784
+ );
27785
+ }
27786
+ if (tpl.workspace?.subtype !== dep.slug) {
27787
+ add(
27788
+ "overlay-subtype",
27789
+ "workspace.subtype",
27790
+ `overlay (compose on "${dep.slug}") must set workspace.subtype to "${dep.slug}" (found "${tpl.workspace?.subtype}")`
27791
+ );
27792
+ }
27793
+ }
27794
+ const blocks = tpl.bento?.blocks ?? [];
27795
+ const authoredWidgets = blocks.filter((b) => b.kind === "widget");
27796
+ const authoredViews = blocks.filter((b) => b.kind === "view");
27797
+ const unknownKind = blocks.filter((b) => b.kind !== "widget" && b.kind !== "view");
27798
+ if (unknownKind.length) {
27799
+ add(
27800
+ "bento-unknown-kind",
27801
+ "bento.blocks",
27802
+ `${unknownKind.length} bento block(s) with unknown kind: ${unknownKind.map((b) => String(b.kind)).join(", ")}`
27803
+ );
27804
+ }
27805
+ const badWidgets = authoredWidgets.filter((b) => !b.widgetType);
27806
+ const badViews = authoredViews.filter((b) => !b.viewName);
27807
+ if (badWidgets.length) {
27808
+ add(
27809
+ "bento-widget-missing-type",
27810
+ "bento.blocks",
27811
+ `${badWidgets.length} widget block(s) missing widgetType`
27812
+ );
27813
+ }
27814
+ if (badViews.length) {
27815
+ add(
27816
+ "bento-view-missing-name",
27817
+ "bento.blocks",
27818
+ `${badViews.length} view block(s) missing viewName`
27819
+ );
27820
+ }
27821
+ if (opts.converters) {
27822
+ const { toWorkspaceDefinition: toWorkspaceDefinition2, toPackageDefinition: toPackageDefinition2 } = opts.converters;
27823
+ const { definition } = toWorkspaceDefinition2(tpl);
27824
+ const pkg = toPackageDefinition2(tpl);
27825
+ if (blocks.length > 0) {
27826
+ const expectW = authoredWidgets.length - badWidgets.length;
27827
+ const expectV = authoredViews.length - badViews.length;
27828
+ const doors = [
27829
+ ["tRPC createFromDefinition", definition.bentoLayout ?? [], definition.bentoViewBlocks ?? []],
27830
+ ["CP packages/apply", pkg.bentoLayout ?? [], pkg.bentoViewBlocks ?? []]
27831
+ ];
27832
+ for (const [door, layout, viewBlocks] of doors) {
27833
+ if (layout.length !== expectW || viewBlocks.length !== expectV) {
27834
+ add(
27835
+ "bento-split-count",
27836
+ "bento.blocks",
27837
+ `[${door}]: authored ${expectW} widget/${expectV} view \u2192 got ${layout.length} bentoLayout/${viewBlocks.length} bentoViewBlocks`
27838
+ );
27839
+ }
27840
+ const layoutBad = layout.filter((b) => typeof b.widgetType !== "string");
27841
+ const viewsBad = viewBlocks.filter(
27842
+ (b) => typeof b.viewName !== "string" || b.kind !== "view"
27843
+ );
27844
+ if (layoutBad.length) {
27845
+ add(
27846
+ "bento-layout-shape",
27847
+ "bento.blocks",
27848
+ `[${door}]: ${layoutBad.length} bentoLayout block(s) without a string widgetType (mis-routed view block?)`
27849
+ );
27850
+ }
27851
+ if (viewsBad.length) {
27852
+ add(
27853
+ "bento-viewblocks-shape",
27854
+ "bento.blocks",
27855
+ `[${door}]: ${viewsBad.length} bentoViewBlocks entry(s) without kind:'view' + string viewName (mis-routed widget block?)`
27856
+ );
27857
+ }
27858
+ }
27859
+ }
27860
+ const authoredViewName = tpl.bento?.viewName;
27861
+ if (authoredViewName) {
27862
+ if (definition.bentoViewName !== authoredViewName) {
27863
+ add(
27864
+ "bento-viewname-parity",
27865
+ "bento.viewName",
27866
+ `[tRPC]: authored bento.viewName "${authoredViewName}" \u2192 got "${definition.bentoViewName}"`
27867
+ );
27868
+ }
27869
+ if (pkg.bentoViewName !== authoredViewName) {
27870
+ add(
27871
+ "bento-viewname-parity",
27872
+ "bento.viewName",
27873
+ `[CP]: authored bento.viewName "${authoredViewName}" \u2192 got "${pkg.bentoViewName}"`
27874
+ );
27875
+ }
27876
+ }
27877
+ const authored = tpl.integrations ?? [];
27878
+ const wsCaps = definition.capabilities ?? [];
27879
+ const pkgCaps = pkg.capabilities ?? [];
27880
+ if (wsCaps.length !== authored.length) {
27881
+ add(
27882
+ "capabilities-count",
27883
+ "integrations",
27884
+ `[tRPC]: authored ${authored.length} integration(s) \u2192 got ${wsCaps.length} capabilities`
27885
+ );
27886
+ }
27887
+ if (JSON.stringify(wsCaps) !== JSON.stringify(pkgCaps)) {
27888
+ add(
27889
+ "capabilities-parity",
27890
+ "integrations",
27891
+ `capability parity mismatch \u2014 tRPC door and CP door emit different capabilities`
27892
+ );
27893
+ }
27894
+ }
27895
+ return { ok: errors.length === 0, errors };
27896
+ }
27897
+
27215
27898
  // src/define.ts
27216
27899
  function toAutomationWire(automations) {
27217
27900
  return automations?.map((a) => ({
@@ -27336,6 +28019,7 @@ function toPackageDefinition(slugOrYaml) {
27336
28019
  slug: tpl.meta.slug,
27337
28020
  icon: tpl.meta.icon,
27338
28021
  color: tpl.meta.color,
28022
+ domain: tpl.meta.domain,
27339
28023
  tags: tpl.meta.tags,
27340
28024
  isPublic: tpl.meta.isPublic ?? true
27341
28025
  },
@@ -27368,16 +28052,26 @@ function toPackageDefinition(slugOrYaml) {
27368
28052
  }
27369
28053
  export {
27370
28054
  DECLARED_DIVERGENCES,
28055
+ OTHER_DOMAIN_ID,
28056
+ OTHER_DOMAIN_LABEL,
27371
28057
  PACKAGE_DEPENDENCY_KINDS,
28058
+ REQUIRED_META_FIELDS,
28059
+ REQUIRED_WORKSPACE_FIELDS,
28060
+ SYSTEM_PROFILES,
28061
+ TEMPLATE_DOMAINS,
27372
28062
  WORKSPACE_TEMPLATES,
27373
28063
  assembleCatalog,
27374
28064
  bundledEdgesOf,
28065
+ collectBaseProfileSlugs,
27375
28066
  computeTemplateUpdates,
27376
28067
  conceptTerm,
28068
+ domainLabel,
27377
28069
  findConceptViolations,
27378
28070
  formatConceptViolations,
27379
28071
  getWorkspaceTemplate,
28072
+ groupByDomain,
27380
28073
  isHashVersion,
28074
+ isKnownDomain,
27381
28075
  layerTemplateGraph,
27382
28076
  listPublicTemplates,
27383
28077
  listWorkspaceTemplates,
@@ -27385,6 +28079,7 @@ export {
27385
28079
  rowToRemoteEntry,
27386
28080
  splitBentoBlocks,
27387
28081
  toPackageDefinition,
27388
- toWorkspaceDefinition
28082
+ toWorkspaceDefinition,
28083
+ validateTemplate
27389
28084
  };
27390
28085
  //# sourceMappingURL=index.js.map