@elevasis/core 0.22.0 → 0.24.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/dist/index.d.ts +3214 -2501
  2. package/dist/index.js +3112 -1222
  3. package/dist/knowledge/index.d.ts +1108 -1264
  4. package/dist/knowledge/index.js +112 -9
  5. package/dist/organization-model/index.d.ts +3214 -2501
  6. package/dist/organization-model/index.js +3112 -1222
  7. package/dist/test-utils/index.d.ts +985 -1103
  8. package/dist/test-utils/index.js +2464 -1165
  9. package/package.json +5 -5
  10. package/src/README.md +14 -14
  11. package/src/__tests__/publish.test.ts +24 -24
  12. package/src/__tests__/template-core-compatibility.test.ts +9 -80
  13. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2389 -2121
  14. package/src/_gen/__tests__/scaffold-contracts.test.ts +30 -30
  15. package/src/auth/multi-tenancy/credentials/__tests__/encryption.test.ts +217 -217
  16. package/src/auth/multi-tenancy/credentials/server/encryption.ts +69 -69
  17. package/src/auth/multi-tenancy/credentials/server/kek-loader.ts +37 -37
  18. package/src/auth/multi-tenancy/index.ts +26 -26
  19. package/src/auth/multi-tenancy/invitations/api-schemas.ts +104 -104
  20. package/src/auth/multi-tenancy/memberships/api-schemas.ts +143 -143
  21. package/src/auth/multi-tenancy/memberships/index.ts +26 -26
  22. package/src/auth/multi-tenancy/memberships/membership.ts +130 -130
  23. package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +194 -194
  24. package/src/auth/multi-tenancy/organizations/api-schemas.ts +136 -136
  25. package/src/auth/multi-tenancy/permissions.test.ts +42 -42
  26. package/src/auth/multi-tenancy/permissions.ts +123 -123
  27. package/src/auth/multi-tenancy/role-management/api-schemas.ts +78 -78
  28. package/src/auth/multi-tenancy/role-management/index.ts +16 -16
  29. package/src/auth/multi-tenancy/theme-presets.ts +45 -45
  30. package/src/auth/multi-tenancy/types.ts +57 -57
  31. package/src/auth/multi-tenancy/users/api-schemas.ts +165 -165
  32. package/src/business/README.md +2 -2
  33. package/src/business/acquisition/activity-events.test.ts +250 -250
  34. package/src/business/acquisition/activity-events.ts +93 -93
  35. package/src/business/acquisition/api-schemas.test.ts +1883 -1843
  36. package/src/business/acquisition/api-schemas.ts +1493 -1500
  37. package/src/business/acquisition/build-templates.test.ts +240 -240
  38. package/src/business/acquisition/build-templates.ts +83 -41
  39. package/src/business/acquisition/crm-next-action.test.ts +262 -262
  40. package/src/business/acquisition/crm-next-action.ts +220 -220
  41. package/src/business/acquisition/crm-priority.test.ts +216 -216
  42. package/src/business/acquisition/crm-priority.ts +349 -349
  43. package/src/business/acquisition/crm-state-actions.test.ts +153 -151
  44. package/src/business/acquisition/deal-ownership.test.ts +351 -351
  45. package/src/business/acquisition/deal-ownership.ts +120 -120
  46. package/src/business/acquisition/derive-actions.test.ts +129 -104
  47. package/src/business/acquisition/derive-actions.ts +74 -84
  48. package/src/business/acquisition/index.ts +171 -170
  49. package/src/business/acquisition/ontology-validation.ts +309 -0
  50. package/src/business/acquisition/stateful.ts +30 -30
  51. package/src/business/acquisition/types.ts +396 -392
  52. package/src/business/clients/api-schemas.test.ts +115 -115
  53. package/src/business/clients/api-schemas.ts +158 -158
  54. package/src/business/clients/index.ts +1 -1
  55. package/src/business/crm/api-schemas.ts +40 -40
  56. package/src/business/crm/index.ts +1 -1
  57. package/src/business/deals/api-schemas.ts +87 -87
  58. package/src/business/deals/index.ts +1 -1
  59. package/src/business/index.ts +5 -5
  60. package/src/business/projects/types.ts +144 -144
  61. package/src/commands/queue/types/task.ts +15 -15
  62. package/src/execution/core/runner-types.ts +61 -61
  63. package/src/execution/core/sse-executions.ts +7 -7
  64. package/src/execution/engine/__tests__/fixtures/test-agents.ts +10 -10
  65. package/src/execution/engine/agent/core/__tests__/agent.test.ts +16 -16
  66. package/src/execution/engine/agent/core/__tests__/error-passthrough.test.ts +4 -4
  67. package/src/execution/engine/agent/core/types.ts +25 -25
  68. package/src/execution/engine/agent/index.ts +6 -6
  69. package/src/execution/engine/agent/reasoning/__tests__/request-builder.test.ts +24 -24
  70. package/src/execution/engine/index.ts +443 -443
  71. package/src/execution/engine/tools/integration/server/adapters/apify/__tests__/apify-run-actor.integration.test.ts +298 -298
  72. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.test.ts +55 -55
  73. package/src/execution/engine/tools/integration/server/adapters/apify/apify-adapter.ts +107 -107
  74. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.test.ts +48 -48
  75. package/src/execution/engine/tools/integration/server/adapters/apollo/apollo-adapter.ts +99 -99
  76. package/src/execution/engine/tools/integration/server/adapters/apollo/index.ts +1 -1
  77. package/src/execution/engine/tools/integration/server/adapters/attio/__tests__/attio-crud.integration.test.ts +363 -363
  78. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/get-record/index.test.ts +162 -162
  79. package/src/execution/engine/tools/integration/server/adapters/attio/fetch/list-records/index.test.ts +316 -316
  80. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.test.ts +18 -18
  81. package/src/execution/engine/tools/integration/server/adapters/clickup/clickup-adapter.ts +194 -194
  82. package/src/execution/engine/tools/integration/server/adapters/clickup/index.ts +7 -7
  83. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-adapter.ts +204 -204
  84. package/src/execution/engine/tools/integration/server/adapters/gmail/gmail-tools.ts +105 -105
  85. package/src/execution/engine/tools/integration/server/adapters/google-calendar/google-calendar-adapter.ts +428 -428
  86. package/src/execution/engine/tools/integration/server/adapters/google-calendar/index.ts +2 -2
  87. package/src/execution/engine/tools/integration/server/adapters/google-sheets/__tests__/google-sheets.integration.test.ts +261 -261
  88. package/src/execution/engine/tools/integration/server/adapters/instantly/instantly-tools.ts +1474 -1474
  89. package/src/execution/engine/tools/integration/server/adapters/millionverifier/millionverifier-tools.ts +103 -103
  90. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.test.ts +88 -88
  91. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/send-email/index.ts +141 -141
  92. package/src/execution/engine/tools/integration/server/adapters/resend/fetch/utils/types.ts +76 -76
  93. package/src/execution/engine/tools/integration/server/adapters/signature-api/signature-api-tools.ts +182 -182
  94. package/src/execution/engine/tools/integration/server/adapters/stripe/stripe-tools.ts +310 -310
  95. package/src/execution/engine/tools/integration/service.test.ts +239 -239
  96. package/src/execution/engine/tools/integration/service.ts +172 -172
  97. package/src/execution/engine/tools/integration/tool.ts +255 -255
  98. package/src/execution/engine/tools/lead-service-types.ts +1005 -1005
  99. package/src/execution/engine/tools/messages.ts +43 -43
  100. package/src/execution/engine/tools/platform/acquisition/company-tools.ts +7 -7
  101. package/src/execution/engine/tools/platform/acquisition/contact-tools.ts +6 -6
  102. package/src/execution/engine/tools/platform/acquisition/list-tools.ts +6 -6
  103. package/src/execution/engine/tools/platform/acquisition/types.ts +280 -280
  104. package/src/execution/engine/tools/platform/email/types.ts +97 -97
  105. package/src/execution/engine/tools/registry.ts +704 -704
  106. package/src/execution/engine/tools/tool-maps.ts +831 -831
  107. package/src/execution/engine/tools/types.ts +234 -234
  108. package/src/execution/engine/workflow/types.ts +202 -202
  109. package/src/execution/external/__tests__/api-schemas.test.ts +127 -127
  110. package/src/execution/external/api-schemas.ts +40 -40
  111. package/src/execution/external/index.ts +1 -1
  112. package/src/index.ts +18 -18
  113. package/src/integrations/credentials/__tests__/api-schemas.test.ts +420 -420
  114. package/src/integrations/credentials/api-schemas.ts +146 -146
  115. package/src/integrations/credentials/schemas.ts +200 -200
  116. package/src/integrations/oauth/__tests__/provider-registry.test.ts +7 -7
  117. package/src/integrations/oauth/provider-registry.ts +74 -74
  118. package/src/integrations/oauth/server/credentials.ts +43 -43
  119. package/src/integrations/webhook-endpoints/__tests__/api-schemas.test.ts +327 -327
  120. package/src/integrations/webhook-endpoints/api-schemas.ts +103 -103
  121. package/src/integrations/webhook-endpoints/types.ts +58 -58
  122. package/src/knowledge/README.md +33 -32
  123. package/src/knowledge/__tests__/queries.test.ts +633 -541
  124. package/src/knowledge/format.ts +100 -99
  125. package/src/knowledge/index.ts +5 -5
  126. package/src/knowledge/published.ts +5 -5
  127. package/src/knowledge/queries.ts +274 -222
  128. package/src/operations/activities/api-schemas.ts +80 -80
  129. package/src/operations/activities/types.ts +64 -64
  130. package/src/organization-model/README.md +149 -109
  131. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
  132. package/src/organization-model/__tests__/defaults.test.ts +168 -194
  133. package/src/organization-model/__tests__/domains/actions.test.ts +78 -0
  134. package/src/organization-model/__tests__/domains/customers.test.ts +48 -44
  135. package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
  136. package/src/organization-model/__tests__/domains/goals.test.ts +110 -96
  137. package/src/organization-model/__tests__/domains/identity.test.ts +4 -3
  138. package/src/organization-model/__tests__/domains/navigation.test.ts +222 -166
  139. package/src/organization-model/__tests__/domains/offerings.test.ts +83 -88
  140. package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
  141. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +30 -30
  142. package/src/organization-model/__tests__/domains/resources.test.ts +396 -175
  143. package/src/organization-model/__tests__/domains/roles.test.ts +463 -402
  144. package/src/organization-model/__tests__/domains/statuses.test.ts +13 -10
  145. package/src/organization-model/__tests__/domains/systems.test.ts +209 -193
  146. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -0
  147. package/src/organization-model/__tests__/foundation.test.ts +47 -75
  148. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
  149. package/src/organization-model/__tests__/graph.test.ts +1336 -149
  150. package/src/organization-model/__tests__/icons.test.ts +10 -1
  151. package/src/organization-model/__tests__/knowledge.test.ts +418 -61
  152. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
  153. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
  154. package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -94
  155. package/src/organization-model/__tests__/recursive-system-schema.test.ts +549 -0
  156. package/src/organization-model/__tests__/resolve.test.ts +303 -42
  157. package/src/organization-model/__tests__/schema.test.ts +863 -153
  158. package/src/organization-model/__tests__/surface-projection.test.ts +284 -174
  159. package/src/organization-model/catalogs/lead-gen.ts +144 -0
  160. package/src/organization-model/content-kinds/config.ts +36 -0
  161. package/src/organization-model/content-kinds/index.ts +78 -0
  162. package/src/organization-model/content-kinds/pipeline.ts +68 -0
  163. package/src/organization-model/content-kinds/registry.ts +44 -0
  164. package/src/organization-model/content-kinds/status.ts +71 -0
  165. package/src/organization-model/content-kinds/template.ts +83 -0
  166. package/src/organization-model/content-kinds/types.ts +117 -0
  167. package/src/organization-model/contracts.ts +27 -17
  168. package/src/organization-model/defaults.ts +489 -107
  169. package/src/organization-model/domains/actions.ts +333 -0
  170. package/src/organization-model/domains/customers.ts +10 -7
  171. package/src/organization-model/domains/entities.ts +144 -0
  172. package/src/organization-model/domains/goals.ts +9 -6
  173. package/src/organization-model/domains/knowledge.ts +128 -54
  174. package/src/organization-model/domains/navigation.ts +139 -416
  175. package/src/organization-model/domains/offerings.ts +15 -10
  176. package/src/organization-model/domains/policies.ts +102 -0
  177. package/src/organization-model/domains/projects.ts +6 -40
  178. package/src/organization-model/domains/prospecting.ts +395 -514
  179. package/src/organization-model/domains/resources.ts +173 -81
  180. package/src/organization-model/domains/roles.ts +96 -93
  181. package/src/organization-model/domains/sales.test.ts +218 -218
  182. package/src/organization-model/domains/sales.ts +380 -589
  183. package/src/organization-model/domains/shared.ts +8 -8
  184. package/src/organization-model/domains/statuses.ts +298 -89
  185. package/src/organization-model/domains/systems.ts +240 -38
  186. package/src/organization-model/foundation.ts +35 -48
  187. package/src/organization-model/graph/build.ts +1035 -279
  188. package/src/organization-model/graph/index.ts +4 -4
  189. package/src/organization-model/graph/link.ts +10 -10
  190. package/src/organization-model/graph/schema.ts +77 -56
  191. package/src/organization-model/graph/types.ts +75 -56
  192. package/src/organization-model/helpers.ts +312 -59
  193. package/src/organization-model/icons.ts +78 -66
  194. package/src/organization-model/index.ts +129 -16
  195. package/src/organization-model/migration-helpers.ts +252 -0
  196. package/src/organization-model/ontology.ts +661 -0
  197. package/src/organization-model/organization-graph.mdx +110 -89
  198. package/src/organization-model/organization-model.mdx +226 -171
  199. package/src/organization-model/published.ts +295 -139
  200. package/src/organization-model/resolve.ts +139 -21
  201. package/src/organization-model/schema.ts +841 -301
  202. package/src/organization-model/surface-projection.ts +212 -218
  203. package/src/organization-model/types.ts +181 -90
  204. package/src/platform/api/types.ts +38 -38
  205. package/src/platform/constants/versions.ts +3 -3
  206. package/src/platform/index.ts +23 -23
  207. package/src/platform/registry/__tests__/command-view.test.ts +5 -7
  208. package/src/platform/registry/__tests__/resource-link.test.ts +35 -30
  209. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +17 -32
  210. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
  211. package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2051
  212. package/src/platform/registry/__tests__/validation.test.ts +1347 -1343
  213. package/src/platform/registry/command-view.ts +10 -10
  214. package/src/platform/registry/index.ts +103 -103
  215. package/src/platform/registry/resource-link.ts +32 -32
  216. package/src/platform/registry/resource-registry.ts +890 -878
  217. package/src/platform/registry/serialization.ts +295 -295
  218. package/src/platform/registry/serialized-types.ts +166 -166
  219. package/src/platform/registry/stats-types.ts +68 -68
  220. package/src/platform/registry/types.ts +425 -425
  221. package/src/platform/registry/validation.ts +745 -743
  222. package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
  223. package/src/platform/utils/validation.ts +425 -425
  224. package/src/projects/api-schemas.test.ts +39 -39
  225. package/src/projects/api-schemas.ts +291 -291
  226. package/src/reference/_generated/contracts.md +2389 -2121
  227. package/src/reference/glossary.md +76 -76
  228. package/src/scaffold-registry/__tests__/index.test.ts +206 -206
  229. package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
  230. package/src/scaffold-registry/index.ts +392 -392
  231. package/src/scaffold-registry/schema.ts +243 -243
  232. package/src/server.ts +289 -289
  233. package/src/supabase/database.types.ts +3153 -3093
  234. package/src/test-utils/README.md +37 -37
  235. package/src/test-utils/entities.ts +108 -108
  236. package/src/test-utils/fixtures/memberships.ts +82 -82
  237. package/src/test-utils/index.ts +12 -12
  238. package/src/test-utils/organization-model.ts +65 -65
  239. package/src/test-utils/published.ts +6 -6
  240. package/src/test-utils/rls/RLSTestContext.ts +588 -588
  241. package/src/test-utils/test-utils.test.ts +44 -49
  242. package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
  243. package/src/organization-model/domains/features.ts +0 -31
  244. package/src/organization-model/domains/operations.ts +0 -85
@@ -19416,74 +19416,653 @@ function makeTask(overrides = {}) {
19416
19416
  ...overrides
19417
19417
  });
19418
19418
  }
19419
+ var OntologyKindSchema = z.enum([
19420
+ "object",
19421
+ "link",
19422
+ "action",
19423
+ "catalog",
19424
+ "event",
19425
+ "interface",
19426
+ "value-type",
19427
+ "property",
19428
+ "group",
19429
+ "surface"
19430
+ ]);
19431
+ var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
19432
+ var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
19433
+ var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
19434
+ var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
19435
+ var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
19436
+ ONTOLOGY_ID_REGEX,
19437
+ "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
19438
+ );
19439
+ function parseOntologyId(id) {
19440
+ const normalized = OntologyIdSchema.parse(id);
19441
+ const match = ONTOLOGY_ID_REGEX.exec(normalized);
19442
+ if (match === null) {
19443
+ throw new Error(`Invalid ontology ID "${id}"`);
19444
+ }
19445
+ return {
19446
+ id: normalized,
19447
+ scope: match[1],
19448
+ kind: match[2],
19449
+ localId: match[3],
19450
+ isGlobal: match[1] === "global"
19451
+ };
19452
+ }
19453
+ function formatOntologyId(input) {
19454
+ return OntologyIdSchema.parse(`${input.scope}:${input.kind}/${input.localId}`);
19455
+ }
19456
+ var OntologyReferenceListSchema = z.array(OntologyIdSchema).default([]).optional();
19457
+ var OntologyRecordBaseSchema = z.object({
19458
+ id: OntologyIdSchema,
19459
+ label: z.string().trim().min(1).max(160).optional(),
19460
+ description: z.string().trim().min(1).max(2e3).optional(),
19461
+ ownerSystemId: z.string().trim().min(1).max(200).optional(),
19462
+ aliases: z.array(OntologyIdSchema).optional()
19463
+ }).passthrough();
19464
+ var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
19465
+ properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
19466
+ storage: z.record(z.string(), z.unknown()).optional()
19467
+ });
19468
+ var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
19469
+ from: OntologyIdSchema,
19470
+ to: OntologyIdSchema,
19471
+ cardinality: z.string().trim().min(1).max(80).optional(),
19472
+ via: z.string().trim().min(1).max(255).optional()
19473
+ });
19474
+ var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
19475
+ actsOn: OntologyReferenceListSchema,
19476
+ input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
19477
+ effects: z.array(z.record(z.string(), z.unknown())).optional()
19478
+ });
19479
+ var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
19480
+ kind: z.string().trim().min(1).max(120).optional(),
19481
+ appliesTo: OntologyIdSchema.optional(),
19482
+ entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
19483
+ });
19484
+ var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
19485
+ payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
19486
+ });
19487
+ var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
19488
+ properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
19489
+ });
19490
+ var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
19491
+ primitive: z.string().trim().min(1).max(120).optional()
19492
+ });
19493
+ var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
19494
+ valueType: OntologyIdSchema.optional(),
19495
+ searchable: z.boolean().optional(),
19496
+ pii: z.boolean().optional()
19497
+ });
19498
+ var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
19499
+ members: OntologyReferenceListSchema
19500
+ });
19501
+ var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
19502
+ route: z.string().trim().min(1).max(500).optional()
19503
+ });
19504
+ var OntologyScopeSchema = z.object({
19505
+ objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
19506
+ linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
19507
+ actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
19508
+ catalogTypes: z.record(OntologyIdSchema, OntologyCatalogTypeSchema).default({}).optional(),
19509
+ eventTypes: z.record(OntologyIdSchema, OntologyEventTypeSchema).default({}).optional(),
19510
+ interfaceTypes: z.record(OntologyIdSchema, OntologyInterfaceTypeSchema).default({}).optional(),
19511
+ valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
19512
+ sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
19513
+ groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
19514
+ surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
19515
+ }).default({});
19516
+ var DEFAULT_ONTOLOGY_SCOPE = {
19517
+ valueTypes: {
19518
+ "global:value-type/uuid": {
19519
+ id: "global:value-type/uuid",
19520
+ label: "UUID",
19521
+ primitive: "string"
19522
+ },
19523
+ "global:value-type/text": {
19524
+ id: "global:value-type/text",
19525
+ label: "Text",
19526
+ primitive: "string"
19527
+ },
19528
+ "global:value-type/url": {
19529
+ id: "global:value-type/url",
19530
+ label: "URL",
19531
+ primitive: "string"
19532
+ },
19533
+ "global:value-type/email": {
19534
+ id: "global:value-type/email",
19535
+ label: "Email",
19536
+ primitive: "string"
19537
+ }
19538
+ }
19539
+ };
19540
+ var SCOPE_KIND = {
19541
+ objectTypes: "object",
19542
+ linkTypes: "link",
19543
+ actionTypes: "action",
19544
+ catalogTypes: "catalog",
19545
+ eventTypes: "event",
19546
+ interfaceTypes: "interface",
19547
+ valueTypes: "value-type",
19548
+ sharedProperties: "property",
19549
+ groups: "group",
19550
+ surfaces: "surface"
19551
+ };
19552
+ var SCOPE_KEYS = Object.keys(SCOPE_KIND);
19553
+ function listResolvedOntologyRecords(index2) {
19554
+ return SCOPE_KEYS.flatMap((scopeKey) => {
19555
+ const kind = SCOPE_KIND[scopeKey];
19556
+ return Object.entries(index2[scopeKey]).sort(([leftId], [rightId]) => leftId.localeCompare(rightId)).map(([id, record]) => ({
19557
+ id,
19558
+ kind,
19559
+ record
19560
+ }));
19561
+ });
19562
+ }
19563
+ function originFromContext(context) {
19564
+ return {
19565
+ kind: context.kind,
19566
+ source: context.source,
19567
+ path: context.path,
19568
+ ...context.systemPath !== void 0 ? { systemPath: context.systemPath } : {},
19569
+ ...context.legacyId !== void 0 ? { legacyId: context.legacyId } : {}
19570
+ };
19571
+ }
19572
+ function createEmptyIndex() {
19573
+ return {
19574
+ objectTypes: {},
19575
+ linkTypes: {},
19576
+ actionTypes: {},
19577
+ catalogTypes: {},
19578
+ eventTypes: {},
19579
+ interfaceTypes: {},
19580
+ valueTypes: {},
19581
+ sharedProperties: {},
19582
+ groups: {},
19583
+ surfaces: {}
19584
+ };
19585
+ }
19586
+ function sortResolvedOntologyIndex(index2) {
19587
+ const sorted = createEmptyIndex();
19588
+ for (const scopeKey of SCOPE_KEYS) {
19589
+ const target = sorted[scopeKey];
19590
+ for (const [id, record] of Object.entries(index2[scopeKey]).sort(
19591
+ ([leftId], [rightId]) => leftId.localeCompare(rightId)
19592
+ )) {
19593
+ target[id] = record;
19594
+ }
19595
+ }
19596
+ return sorted;
19597
+ }
19598
+ function childSystemsOf(system) {
19599
+ return system.systems ?? system.subsystems ?? {};
19600
+ }
19601
+ function addRecord(index2, diagnostics, sourcesById, scopeKey, record, context) {
19602
+ let parsed;
19603
+ try {
19604
+ parsed = parseOntologyId(record.id);
19605
+ } catch {
19606
+ diagnostics.push({
19607
+ code: "invalid_ontology_id",
19608
+ message: `Invalid ontology ID "${record.id}" from ${context.source} at ${context.path.join(".")}`,
19609
+ id: record.id,
19610
+ path: context.path,
19611
+ source: context.source,
19612
+ origin: originFromContext(context)
19613
+ });
19614
+ return;
19615
+ }
19616
+ const expectedKind = SCOPE_KIND[scopeKey];
19617
+ if (parsed.kind !== expectedKind) {
19618
+ diagnostics.push({
19619
+ code: "ontology_kind_mismatch",
19620
+ message: `Ontology ID "${record.id}" has kind "${parsed.kind}" but was authored in ${scopeKey} (${expectedKind}) at ${context.path.join(".")}`,
19621
+ id: record.id,
19622
+ path: context.path,
19623
+ source: context.source,
19624
+ origin: originFromContext(context)
19625
+ });
19626
+ return;
19627
+ }
19628
+ const existing = sourcesById.get(parsed.id);
19629
+ if (existing !== void 0) {
19630
+ diagnostics.push({
19631
+ code: "duplicate_ontology_id",
19632
+ message: `Duplicate ontology ID "${parsed.id}" from ${context.source} at ${context.path.join(".")} conflicts with ${existing.source} at ${existing.path.join(".")}`,
19633
+ id: parsed.id,
19634
+ path: context.path,
19635
+ source: context.source,
19636
+ origin: originFromContext(context),
19637
+ existingSource: existing.source,
19638
+ existingOrigin: originFromContext(existing)
19639
+ });
19640
+ return;
19641
+ }
19642
+ sourcesById.set(parsed.id, context);
19643
+ index2[scopeKey][parsed.id] = {
19644
+ ...record,
19645
+ origin: originFromContext(context)
19646
+ };
19647
+ }
19648
+ function addScope(index2, diagnostics, sourcesById, scope, source, path) {
19649
+ if (scope === void 0) return;
19650
+ for (const scopeKey of SCOPE_KEYS) {
19651
+ const records = scope[scopeKey] ?? {};
19652
+ for (const [key, record] of Object.entries(records)) {
19653
+ addRecord(index2, diagnostics, sourcesById, scopeKey, record, {
19654
+ source,
19655
+ path: [...path, scopeKey, key],
19656
+ kind: "authored",
19657
+ systemPath: source.startsWith("system:") ? source.slice("system:".length, -".ontology".length) : void 0
19658
+ });
19659
+ }
19660
+ }
19661
+ }
19662
+ function legacyObjectId(entity) {
19663
+ return formatOntologyId({ scope: entity.ownedBySystemId, kind: "object", localId: entity.id });
19664
+ }
19665
+ function legacyActionOwner(action, entities) {
19666
+ const firstAffectedEntityId = action.affects?.find((entityId) => entities[entityId] !== void 0);
19667
+ if (firstAffectedEntityId !== void 0) {
19668
+ return entities[firstAffectedEntityId].ownedBySystemId;
19669
+ }
19670
+ if (typeof action.scope === "object") {
19671
+ return action.scope.domain;
19672
+ }
19673
+ return "global";
19674
+ }
19675
+ function addLegacyEntityProjections(index2, diagnostics, sourcesById, entities) {
19676
+ for (const entity of Object.values(entities)) {
19677
+ const objectType = {
19678
+ id: legacyObjectId(entity),
19679
+ label: entity.label,
19680
+ description: entity.description,
19681
+ ownerSystemId: entity.ownedBySystemId,
19682
+ ...entity.table !== void 0 ? {
19683
+ storage: {
19684
+ kind: "table",
19685
+ table: entity.table
19686
+ }
19687
+ } : {},
19688
+ legacyEntityId: entity.id,
19689
+ ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
19690
+ ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
19691
+ };
19692
+ addRecord(index2, diagnostics, sourcesById, "objectTypes", objectType, {
19693
+ source: "legacy.entities",
19694
+ path: ["entities", entity.id],
19695
+ kind: "projected",
19696
+ systemPath: entity.ownedBySystemId,
19697
+ legacyId: entity.id
19698
+ });
19699
+ entity.links?.forEach((link, linkIndex) => {
19700
+ const targetEntity = entities[link.toEntity];
19701
+ if (targetEntity === void 0) return;
19702
+ const linkType = {
19703
+ id: formatOntologyId({
19704
+ scope: entity.ownedBySystemId,
19705
+ kind: "link",
19706
+ localId: `${entity.id}-${link.toEntity}-${linkIndex}`
19707
+ }),
19708
+ label: link.label ?? link.kind,
19709
+ ownerSystemId: entity.ownedBySystemId,
19710
+ from: legacyObjectId(entity),
19711
+ to: legacyObjectId(targetEntity),
19712
+ cardinality: link.kind,
19713
+ ...link.via !== void 0 ? { via: link.via } : {},
19714
+ legacyEntityId: entity.id
19715
+ };
19716
+ addRecord(index2, diagnostics, sourcesById, "linkTypes", linkType, {
19717
+ source: "legacy.entities.links",
19718
+ path: ["entities", entity.id, "links", linkIndex],
19719
+ kind: "projected",
19720
+ systemPath: entity.ownedBySystemId,
19721
+ legacyId: `${entity.id}.links.${linkIndex}`
19722
+ });
19723
+ });
19724
+ }
19725
+ }
19726
+ function addLegacyActionProjections(index2, diagnostics, sourcesById, actions, entities) {
19727
+ for (const action of Object.values(actions)) {
19728
+ const ownerSystemId = legacyActionOwner(action, entities);
19729
+ const actionType = {
19730
+ id: formatOntologyId({ scope: ownerSystemId, kind: "action", localId: action.id }),
19731
+ label: action.label,
19732
+ description: action.description,
19733
+ ownerSystemId,
19734
+ actsOn: action.affects?.map((entityId) => entities[entityId] ? legacyObjectId(entities[entityId]) : void 0).filter((id) => id !== void 0),
19735
+ ...action.resourceId !== void 0 ? { resourceId: action.resourceId } : {},
19736
+ ...action.invocations !== void 0 ? { invocations: action.invocations } : {},
19737
+ ...action.lifecycle !== void 0 ? { lifecycle: action.lifecycle } : {},
19738
+ legacyActionId: action.id
19739
+ };
19740
+ addRecord(index2, diagnostics, sourcesById, "actionTypes", actionType, {
19741
+ source: "legacy.actions",
19742
+ path: ["actions", action.id],
19743
+ kind: "projected",
19744
+ systemPath: ownerSystemId,
19745
+ legacyId: action.id
19746
+ });
19747
+ }
19748
+ }
19749
+ function addSystemContentProjections(index2, diagnostics, sourcesById, systemPath, system, schemaPath) {
19750
+ const content = system.content ?? {};
19751
+ for (const [localId, node] of Object.entries(content)) {
19752
+ if (node.kind !== "schema") continue;
19753
+ const entries = Object.fromEntries(
19754
+ Object.entries(content).filter(([, candidate]) => candidate.parentContentId === localId).map(([entryId, candidate]) => [
19755
+ entryId,
19756
+ {
19757
+ label: candidate.label ?? entryId,
19758
+ type: candidate.type,
19759
+ ...candidate.description !== void 0 ? { description: candidate.description } : {},
19760
+ ...candidate.data !== void 0 ? candidate.data : {}
19761
+ }
19762
+ ])
19763
+ );
19764
+ const catalogType = {
19765
+ id: formatOntologyId({ scope: systemPath, kind: "catalog", localId }),
19766
+ label: node.label ?? localId,
19767
+ description: node.description,
19768
+ ownerSystemId: systemPath,
19769
+ kind: node.type,
19770
+ ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
19771
+ ...Object.keys(entries).length > 0 ? { entries } : {},
19772
+ ...node.data !== void 0 ? { data: node.data } : {},
19773
+ legacyContentId: `${systemPath}:${localId}`
19774
+ };
19775
+ addRecord(index2, diagnostics, sourcesById, "catalogTypes", catalogType, {
19776
+ source: "legacy.system.content",
19777
+ path: [...schemaPath, "content", localId],
19778
+ kind: "projected",
19779
+ systemPath,
19780
+ legacyId: `${systemPath}:${localId}`
19781
+ });
19782
+ }
19783
+ }
19784
+ function addSystemScopes(index2, diagnostics, sourcesById, systems, prefix, schemaPath) {
19785
+ for (const [key, system] of Object.entries(systems)) {
19786
+ const systemPath = prefix ? `${prefix}.${key}` : key;
19787
+ const currentPath = [...schemaPath, key];
19788
+ addScope(index2, diagnostics, sourcesById, system.ontology, `system:${systemPath}.ontology`, [
19789
+ ...currentPath,
19790
+ "ontology"
19791
+ ]);
19792
+ addSystemContentProjections(index2, diagnostics, sourcesById, systemPath, system, currentPath);
19793
+ addSystemScopes(index2, diagnostics, sourcesById, childSystemsOf(system), systemPath, [
19794
+ ...currentPath,
19795
+ system.systems !== void 0 ? "systems" : "subsystems"
19796
+ ]);
19797
+ }
19798
+ }
19799
+ function compileOrganizationOntology(model) {
19800
+ const ontology = createEmptyIndex();
19801
+ const diagnostics = [];
19802
+ const sourcesById = /* @__PURE__ */ new Map();
19803
+ addScope(ontology, diagnostics, sourcesById, model.ontology, "organization.ontology", ["ontology"]);
19804
+ addSystemScopes(ontology, diagnostics, sourcesById, model.systems ?? {}, "", ["systems"]);
19805
+ addLegacyEntityProjections(ontology, diagnostics, sourcesById, model.entities ?? {});
19806
+ addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
19807
+ return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
19808
+ }
19809
+
19810
+ // src/organization-model/content-kinds/registry.ts
19811
+ function defineContentType(def) {
19812
+ return def;
19813
+ }
19814
+ var ContentNodeBaseSchema = z.object({
19815
+ /** Human-readable label for the content node. */
19816
+ label: z.string().trim().min(1).max(120).meta({ label: "Label" }),
19817
+ /** Optional one-paragraph description. */
19818
+ description: z.string().trim().min(1).max(2e3).optional().meta({ label: "Description" }),
19819
+ /** Optional display order within the system content map. */
19820
+ order: z.number().int().optional().meta({ label: "Order" }),
19821
+ /**
19822
+ * Local NodeId of the parent content node within the SAME system.
19823
+ * Per B4/L9: MUST resolve to a sibling in the same `system.content` map.
19824
+ * Per L19: parent and child MUST share the same `kind` (meta-category).
19825
+ */
19826
+ parentContentId: z.string().trim().min(1).max(200).optional().meta({ label: "Parent content id" })
19827
+ });
19828
+ var ContentNodeSchema = ContentNodeBaseSchema.extend({
19829
+ /** Meta-category (e.g. 'schema', 'config', 'knowledge', tenant-defined). */
19830
+ kind: z.string().trim().min(1).max(100).meta({ label: "Kind" }),
19831
+ /** Specific family within the meta-category (e.g. 'pipeline', 'kv'). */
19832
+ type: z.string().trim().min(1).max(100).meta({ label: "Type" }),
19833
+ /** Payload data; validated against registered payloadSchema when (kind, type) is known. */
19834
+ data: z.record(z.string(), z.unknown()).optional().meta({ label: "Data" })
19835
+ });
19836
+ z.object({
19837
+ /** Meta-category (tenant-defined or registry-shipped). */
19838
+ kind: z.string().trim().min(1).max(100).meta({ label: "Kind" }),
19839
+ /** Specific family within the meta-category. */
19840
+ type: z.string().trim().min(1).max(100).meta({ label: "Type" }),
19841
+ /** Human-readable label shown in the KB tree and describe views. */
19842
+ label: z.string().trim().min(1).max(120).meta({ label: "Label" }),
19843
+ /** Optional description. */
19844
+ description: z.string().trim().min(1).max(2e3).optional().meta({ label: "Description" }),
19845
+ /**
19846
+ * Which KB tree group this extension renders in.
19847
+ * Per L6: 'business-model' places it alongside Customers / Offerings / Goals.
19848
+ */
19849
+ treeGroup: z.union([z.enum(["profile", "business-model", "systems", "graph", "governance-wiring"]), z.string().min(1).max(100)]).meta({ label: "Tree group" }),
19850
+ /** Untyped payload; shape governed by the registered payloadSchema when available. */
19851
+ data: z.record(z.string(), z.unknown()).optional().meta({ label: "Data" })
19852
+ });
19853
+ var PipelinePayloadSchema = z.object({
19854
+ /**
19855
+ * Local NodeId of the entity this pipeline applies to (e.g. 'crm.deal').
19856
+ * `.meta({ ref: 'entity' })` enables SchemaDrivenFieldList to render a
19857
+ * clickable graph link to the referenced entity node.
19858
+ */
19859
+ entityId: z.string().trim().min(1).max(200).meta({ label: "Entity", ref: "entity", hint: "The entity type this pipeline tracks" }),
19860
+ /**
19861
+ * Optional Kanban column color token for UI rendering.
19862
+ */
19863
+ kanbanColor: z.string().trim().min(1).max(40).optional().meta({ label: "Kanban color", hint: "UI color token" })
19864
+ });
19865
+ var pipelineKind = defineContentType({
19866
+ kind: "schema",
19867
+ type: "pipeline",
19868
+ label: "Pipeline",
19869
+ description: "A named progression pipeline that applies to a specific entity type.",
19870
+ payloadSchema: PipelinePayloadSchema,
19871
+ parentTypes: []
19872
+ });
19873
+ var StagePayloadSchema = z.object({
19874
+ /**
19875
+ * Semantic classification for this stage.
19876
+ * Drives color, icon, and CRM-priority logic in consuming views.
19877
+ * Optional — prospecting stages use data.entityKind instead.
19878
+ * Enum aligned with SalesStageSemanticClassSchema (sales.ts).
19879
+ */
19880
+ semanticClass: z.enum(["open", "active", "nurturing", "closed_won", "closed_lost", "won", "lost", "closed"]).optional().meta({ label: "Semantic class", hint: "Semantic meaning of this stage", color: "blue" })
19881
+ });
19882
+ var stageKind = defineContentType({
19883
+ kind: "schema",
19884
+ type: "stage",
19885
+ label: "Stage",
19886
+ description: "A stage within a pipeline. Must be parented under a schema:pipeline content node.",
19887
+ payloadSchema: StagePayloadSchema,
19888
+ parentTypes: ["schema:pipeline"]
19889
+ });
19890
+ var TemplatePayloadSchema = z.object({
19891
+ /**
19892
+ * Optional description surfaced in the KB describe view and tooling.
19893
+ */
19894
+ description: z.string().trim().min(1).max(2e3).optional().meta({ label: "Description", hint: "What this template is used for" })
19895
+ });
19896
+ var templateKind = defineContentType({
19897
+ kind: "schema",
19898
+ type: "template",
19899
+ label: "Template",
19900
+ description: "A named build template (e.g. a prospecting pipeline sequence).",
19901
+ payloadSchema: TemplatePayloadSchema,
19902
+ parentTypes: []
19903
+ });
19904
+ var TemplateStepPayloadSchema = z.object({
19905
+ /**
19906
+ * Which entity type this step primarily operates on.
19907
+ */
19908
+ primaryEntity: z.enum(["company", "contact"]).meta({ label: "Primary entity", hint: "Entity type this step processes", color: "blue" }),
19909
+ /**
19910
+ * Action key identifying the workflow action executed by this step.
19911
+ * `.meta({ ref: 'action' })` enables SchemaDrivenFieldList to render a
19912
+ * clickable graph link.
19913
+ */
19914
+ actionKey: z.string().trim().min(1).max(200).meta({ label: "Action", ref: "action", hint: "Workflow action executed by this step" }),
19915
+ /**
19916
+ * IDs of sibling step local NodeIds this step depends on.
19917
+ */
19918
+ dependsOn: z.array(z.string().trim().min(1).max(200)).optional().meta({ label: "Depends on", hint: "Local NodeIds of prerequisite steps" })
19919
+ });
19920
+ var templateStepKind = defineContentType({
19921
+ kind: "schema",
19922
+ type: "template-step",
19923
+ label: "Template Step",
19924
+ description: "A step within a build template. Must be parented under a schema:template content node.",
19925
+ payloadSchema: TemplateStepPayloadSchema,
19926
+ parentTypes: ["schema:template"]
19927
+ });
19928
+ var StatusFlowPayloadSchema = z.object({
19929
+ /**
19930
+ * Which entity scope this status flow governs.
19931
+ */
19932
+ appliesTo: z.enum(["project", "milestone", "task"]).meta({ label: "Applies to", hint: "Entity scope governed by this status flow", color: "blue" })
19933
+ });
19934
+ var statusFlowKind = defineContentType({
19935
+ kind: "schema",
19936
+ type: "status-flow",
19937
+ label: "Status Flow",
19938
+ description: "A named set of statuses governing a project, milestone, or task entity.",
19939
+ payloadSchema: StatusFlowPayloadSchema,
19940
+ parentTypes: []
19941
+ });
19942
+ var StatusPayloadSchema = z.object({
19943
+ /**
19944
+ * Semantic classification string for this status.
19945
+ * Free-form to allow tenant-defined classifications (e.g. 'active', 'blocked',
19946
+ * 'completed'). Used by UI to apply color and icon fallbacks.
19947
+ * Optional — status nodes may omit this when the label is self-descriptive.
19948
+ */
19949
+ semanticClass: z.string().trim().min(1).max(100).optional().meta({ label: "Semantic class", hint: "Semantic meaning of this status (e.g. active, blocked, completed)" }),
19950
+ /**
19951
+ * Optional UI color token override for this status.
19952
+ */
19953
+ color: z.string().trim().min(1).max(40).optional().meta({ label: "Color", hint: "UI color token" })
19954
+ });
19955
+ var statusKind = defineContentType({
19956
+ kind: "schema",
19957
+ type: "status",
19958
+ label: "Status",
19959
+ description: "A single status within a status flow. Must be parented under a schema:status-flow content node.",
19960
+ payloadSchema: StatusPayloadSchema,
19961
+ parentTypes: ["schema:status-flow"]
19962
+ });
19963
+ var ConfigKvPayloadSchema = z.object({
19964
+ /**
19965
+ * Flat key-value entries. Values are JSON primitives.
19966
+ * Keys are short identifiers (e.g. 'maxBatchSize', 'featureEnabled').
19967
+ */
19968
+ entries: z.record(z.string().trim().min(1).max(200), z.union([z.string(), z.number(), z.boolean(), z.null()])).meta({ label: "Entries", hint: "Key-value configuration entries (string, number, boolean, or null values)" })
19969
+ });
19970
+ var configKvKind = defineContentType({
19971
+ kind: "config",
19972
+ type: "kv",
19973
+ label: "Key-Value Config",
19974
+ description: "A flat key-value configuration store co-located with a system. Values are JSON primitives.",
19975
+ payloadSchema: ConfigKvPayloadSchema,
19976
+ parentTypes: []
19977
+ });
19978
+
19979
+ // src/organization-model/content-kinds/index.ts
19980
+ var CONTENT_KIND_REGISTRY = {
19981
+ "schema:pipeline": pipelineKind,
19982
+ "schema:stage": stageKind,
19983
+ "schema:template": templateKind,
19984
+ "schema:template-step": templateStepKind,
19985
+ "schema:status-flow": statusFlowKind,
19986
+ "schema:status": statusKind,
19987
+ "config:kv": configKvKind
19988
+ };
19989
+ function lookupContentType(kind, type3) {
19990
+ const key = `${kind}:${type3}`;
19991
+ return CONTENT_KIND_REGISTRY[key];
19992
+ }
19419
19993
  var ORGANIZATION_MODEL_ICON_TOKENS = [
19420
- "nav.dashboard",
19421
- "nav.calendar",
19422
- "nav.sales",
19423
- "nav.crm",
19424
- "nav.lead-gen",
19425
- "nav.projects",
19426
- "nav.operations",
19427
- "nav.monitoring",
19428
- "nav.knowledge",
19429
- "nav.settings",
19430
- "nav.admin",
19431
- "nav.archive",
19432
- "knowledge.playbook",
19433
- "knowledge.strategy",
19434
- "knowledge.reference",
19435
- "feature.dashboard",
19436
- "feature.calendar",
19437
- "feature.business",
19438
- "feature.sales",
19439
- "feature.crm",
19440
- "feature.finance",
19441
- "feature.lead-gen",
19442
- "feature.platform",
19443
- "feature.projects",
19444
- "feature.operations",
19445
- "feature.knowledge",
19446
- "feature.monitoring",
19447
- "feature.settings",
19448
- "feature.admin",
19449
- "feature.archive",
19450
- "feature.seo",
19451
- "resource.agent",
19452
- "resource.workflow",
19453
- "resource.integration",
19454
- "resource.database",
19455
- "resource.user",
19456
- "resource.team",
19457
- "integration.gmail",
19458
- "integration.google-sheets",
19459
- "integration.attio",
19460
- "surface.dashboard",
19461
- "surface.calendar",
19462
- "surface.overview",
19463
- "surface.command-view",
19464
- "surface.command-queue",
19465
- "surface.pipeline",
19466
- "surface.lists",
19467
- "surface.resources",
19468
- "surface.settings",
19469
- "status.success",
19470
- "status.error",
19471
- "status.warning",
19472
- "status.info",
19473
- "status.pending",
19474
- "action.approve",
19475
- "action.reject",
19476
- "action.retry",
19477
- "action.edit",
19478
- "action.view",
19479
- "action.launch",
19480
- "action.message",
19481
- "action.escalate",
19482
- "action.promote",
19483
- "action.submit",
19484
- "action.email"
19994
+ // Navigation / app areas
19995
+ "dashboard",
19996
+ "calendar",
19997
+ "sales",
19998
+ "crm",
19999
+ "lead-gen",
20000
+ "projects",
20001
+ "operations",
20002
+ "monitoring",
20003
+ "knowledge",
20004
+ "settings",
20005
+ "admin",
20006
+ "archive",
20007
+ "business",
20008
+ "finance",
20009
+ "platform",
20010
+ "seo",
20011
+ // Knowledge kinds
20012
+ "playbook",
20013
+ "strategy",
20014
+ "reference",
20015
+ // Resource kinds
20016
+ "agent",
20017
+ "workflow",
20018
+ "integration",
20019
+ "database",
20020
+ "user",
20021
+ "team",
20022
+ // Integration specifics
20023
+ "gmail",
20024
+ "google-sheets",
20025
+ "attio",
20026
+ // Surface / UI views
20027
+ "overview",
20028
+ "command-view",
20029
+ "command-queue",
20030
+ "pipeline",
20031
+ "lists",
20032
+ "resources",
20033
+ // Actions
20034
+ "approve",
20035
+ "reject",
20036
+ "retry",
20037
+ "edit",
20038
+ "view",
20039
+ "launch",
20040
+ "message",
20041
+ "escalate",
20042
+ "promote",
20043
+ "submit",
20044
+ "email",
20045
+ // Status
20046
+ "success",
20047
+ "error",
20048
+ "warning",
20049
+ "info",
20050
+ "pending",
20051
+ // OM / UI group icons
20052
+ "bolt",
20053
+ "building",
20054
+ "briefcase",
20055
+ "apps",
20056
+ "graph",
20057
+ "shield",
20058
+ "users",
20059
+ "chart-bar",
20060
+ "search"
19485
20061
  ];
19486
- var CustomIconTokenSchema = z.string().trim().max(80).regex(/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "Custom icon tokens must start with custom.");
20062
+ var CustomIconTokenSchema = z.string().trim().max(80).regex(
20063
+ /^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
20064
+ 'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
20065
+ );
19487
20066
  var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
19488
20067
  var OrganizationModelIconTokenSchema = z.union([
19489
20068
  OrganizationModelBuiltinIconTokenSchema,
@@ -19527,10 +20106,10 @@ DisplayMetadataSchema.extend({
19527
20106
  id: ModelIdSchema,
19528
20107
  resourceId: z.string().trim().min(1).max(255),
19529
20108
  resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint"]),
19530
- featureIds: ReferenceIdsSchema,
20109
+ systemIds: ReferenceIdsSchema,
19531
20110
  entityIds: ReferenceIdsSchema,
19532
20111
  surfaceIds: ReferenceIdsSchema,
19533
- capabilityIds: ReferenceIdsSchema,
20112
+ actionIds: ReferenceIdsSchema,
19534
20113
  /** Optional tech-stack metadata for external-SaaS integrations. */
19535
20114
  techStack: TechStackEntrySchema.optional()
19536
20115
  });
@@ -19552,637 +20131,8 @@ var DEFAULT_ORGANIZATION_MODEL_BRANDING = {
19552
20131
  shortName: "Elevasis",
19553
20132
  logos: {}
19554
20133
  };
19555
- var SalesStageSemanticClassSchema = z.enum(["open", "active", "nurturing", "closed_won", "closed_lost"]);
19556
- var SalesStageSchema = DisplayMetadataSchema.extend({
19557
- id: ModelIdSchema,
19558
- order: z.number().int().min(0),
19559
- semanticClass: SalesStageSemanticClassSchema,
19560
- surfaceIds: ReferenceIdsSchema,
19561
- resourceIds: ReferenceIdsSchema
19562
- });
19563
- var SalesPipelineSchema = z.object({
19564
- id: ModelIdSchema,
19565
- label: z.string().trim().min(1).max(120),
19566
- description: DescriptionSchema.optional(),
19567
- entityId: ModelIdSchema,
19568
- stages: z.array(SalesStageSchema).min(1)
19569
- });
19570
- var OrganizationModelSalesSchema = z.object({
19571
- entityId: ModelIdSchema,
19572
- defaultPipelineId: ModelIdSchema,
19573
- pipelines: z.array(SalesPipelineSchema).min(1)
19574
- });
19575
- var DEFAULT_ORGANIZATION_MODEL_SALES = {
19576
- entityId: "crm.deal",
19577
- defaultPipelineId: "default",
19578
- pipelines: [
19579
- {
19580
- id: "default",
19581
- label: "Default Pipeline",
19582
- entityId: "crm.deal",
19583
- stages: [
19584
- {
19585
- id: "interested",
19586
- label: "Interested",
19587
- color: "blue",
19588
- order: 1,
19589
- semanticClass: "open",
19590
- surfaceIds: ["crm.pipeline"],
19591
- resourceIds: []
19592
- },
19593
- {
19594
- id: "proposal",
19595
- label: "Proposal",
19596
- color: "yellow",
19597
- order: 2,
19598
- semanticClass: "active",
19599
- surfaceIds: ["crm.pipeline"],
19600
- resourceIds: []
19601
- },
19602
- {
19603
- id: "closing",
19604
- label: "Closing",
19605
- color: "lime",
19606
- order: 3,
19607
- semanticClass: "active",
19608
- surfaceIds: ["crm.pipeline"],
19609
- resourceIds: []
19610
- },
19611
- {
19612
- id: "closed_won",
19613
- label: "Closed Won",
19614
- color: "green",
19615
- order: 4,
19616
- semanticClass: "closed_won",
19617
- surfaceIds: ["crm.pipeline"],
19618
- resourceIds: []
19619
- },
19620
- {
19621
- id: "closed_lost",
19622
- label: "Closed Lost",
19623
- color: "red",
19624
- order: 5,
19625
- semanticClass: "closed_lost",
19626
- surfaceIds: ["crm.pipeline"],
19627
- resourceIds: []
19628
- },
19629
- {
19630
- id: "nurturing",
19631
- label: "Nurturing",
19632
- color: "grape",
19633
- order: 6,
19634
- semanticClass: "nurturing",
19635
- surfaceIds: ["crm.pipeline"],
19636
- resourceIds: []
19637
- }
19638
- ]
19639
- }
19640
- ]
19641
- };
19642
- var LEAD_GEN_STAGE_CATALOG = {
19643
- // Prospecting — company population
19644
- scraped: {
19645
- key: "scraped",
19646
- label: "Scraped",
19647
- description: "Company was scraped from a source directory (Apify actor run).",
19648
- order: 1,
19649
- entity: "company"
19650
- },
19651
- populated: {
19652
- key: "populated",
19653
- label: "Companies found",
19654
- description: "Companies have been found and added to the lead-gen list.",
19655
- order: 2,
19656
- entity: "company"
19657
- },
19658
- crawled: {
19659
- key: "crawled",
19660
- label: "Websites crawled",
19661
- description: "Company websites have been crawled (e.g. via Apify) and raw page content stored for downstream LLM analysis.",
19662
- order: 2.5,
19663
- entity: "company"
19664
- },
19665
- extracted: {
19666
- key: "extracted",
19667
- label: "Websites analyzed",
19668
- description: "Company websites have been analyzed for business signals.",
19669
- order: 3,
19670
- entity: "company"
19671
- },
19672
- enriched: {
19673
- key: "enriched",
19674
- label: "Enriched",
19675
- description: "Company or contact enriched with third-party data (e.g. Tomba, Anymailfinder).",
19676
- order: 4,
19677
- entity: "company"
19678
- },
19679
- "decision-makers-enriched": {
19680
- key: "decision-makers-enriched",
19681
- label: "Decision-makers found",
19682
- description: "Decision-maker contacts discovered and attached to a qualified company.",
19683
- order: 6,
19684
- entity: "company",
19685
- recordEntity: "contact",
19686
- recordStageKey: "discovered"
19687
- },
19688
- // Prospecting — contact discovery
19689
- discovered: {
19690
- key: "discovered",
19691
- label: "Decision-makers found",
19692
- description: "Decision-maker contact details have been found.",
19693
- order: 5,
19694
- entity: "contact"
19695
- },
19696
- verified: {
19697
- key: "verified",
19698
- label: "Emails verified",
19699
- description: "Contact email addresses have been checked for deliverability.",
19700
- order: 7,
19701
- entity: "contact"
19702
- },
19703
- // Qualification
19704
- qualified: {
19705
- key: "qualified",
19706
- label: "Companies qualified",
19707
- description: "Companies have been scored against the qualification criteria.",
19708
- order: 8,
19709
- entity: "company"
19710
- },
19711
- // Outreach
19712
- personalized: {
19713
- key: "personalized",
19714
- label: "Personalized",
19715
- description: "Outreach message personalized for the contact (Instantly personalization workflow).",
19716
- order: 9,
19717
- entity: "contact"
19718
- },
19719
- uploaded: {
19720
- key: "uploaded",
19721
- label: "Reviewed and exported",
19722
- description: "Approved records have been reviewed and exported for handoff.",
19723
- order: 10,
19724
- entity: "company",
19725
- additionalEntities: ["contact"]
19726
- },
19727
- interested: {
19728
- key: "interested",
19729
- label: "Interested",
19730
- description: "Contact replied with a positive signal (Instantly reply-handler transition).",
19731
- order: 11,
19732
- entity: "contact"
19733
- }
19734
- };
19735
- var ProjectsDomainStateSchema = DisplayMetadataSchema.extend({
19736
- id: ModelIdSchema,
19737
- order: z.number().int().min(0)
19738
- });
19739
- var OrganizationModelProjectsSchema = z.object({
19740
- projectEntityId: ModelIdSchema,
19741
- milestoneEntityId: ModelIdSchema,
19742
- taskEntityId: ModelIdSchema,
19743
- projectStatuses: z.array(ProjectsDomainStateSchema).min(1),
19744
- milestoneStatuses: z.array(ProjectsDomainStateSchema).min(1),
19745
- taskStatuses: z.array(ProjectsDomainStateSchema).min(1)
19746
- });
19747
- var DEFAULT_ORGANIZATION_MODEL_PROJECTS = {
19748
- projectEntityId: "delivery.project",
19749
- milestoneEntityId: "delivery.milestone",
19750
- taskEntityId: "delivery.task",
19751
- projectStatuses: [
19752
- { id: "active", label: "Active", order: 1 },
19753
- { id: "on_track", label: "On Track", order: 2 },
19754
- { id: "at_risk", label: "At Risk", order: 3 },
19755
- { id: "blocked", label: "Blocked", order: 4 },
19756
- { id: "paused", label: "Paused", order: 5 },
19757
- { id: "completed", label: "Completed", order: 6 }
19758
- ],
19759
- milestoneStatuses: [
19760
- { id: "upcoming", label: "Upcoming", order: 1 },
19761
- { id: "in_progress", label: "In Progress", order: 2 },
19762
- { id: "blocked", label: "Blocked", order: 3 },
19763
- { id: "overdue", label: "Overdue", order: 4 },
19764
- { id: "completed", label: "Completed", order: 5 }
19765
- ],
19766
- taskStatuses: [
19767
- { id: "planned", label: "Planned", order: 1 },
19768
- { id: "in_progress", label: "In Progress", order: 2 },
19769
- { id: "blocked", label: "Blocked", order: 3 },
19770
- { id: "submitted", label: "Submitted", order: 4 },
19771
- { id: "approved", label: "Approved", order: 5 },
19772
- { id: "revision_requested", label: "Revision Requested", order: 6 },
19773
- { id: "rejected", label: "Rejected", order: 7 },
19774
- { id: "cancelled", label: "Cancelled", order: 8 },
19775
- { id: "completed", label: "Completed", order: 9 }
19776
- ]
19777
- };
19778
- var NodeIdPathSchema = z.string().trim().min(1).max(100).regex(/^([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node IDs must be lowercase dotted paths");
19779
- var NodeIdStringSchema = z.string().trim().min(1).max(200).regex(/^[a-z]+:([a-z0-9-]+)(\.[a-z0-9-]+)*$/, "Node references must use kind:dotted-path");
19780
- var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]);
19781
- var FeatureSchema = z.object({
19782
- id: NodeIdPathSchema,
19783
- label: LabelSchema,
19784
- description: DescriptionSchema.optional(),
19785
- enabled: z.boolean().default(true),
19786
- path: PathSchema.optional(),
19787
- icon: IconNameSchema.optional(),
19788
- color: ColorTokenSchema.optional(),
19789
- uiPosition: UiPositionSchema.optional(),
19790
- requiresAdmin: z.boolean().optional(),
19791
- devOnly: z.boolean().optional()
19792
- });
19793
- var ProspectingLifecycleStageSchema = DisplayMetadataSchema.extend({
19794
- id: ModelIdSchema,
19795
- order: z.number().min(0)
19796
- });
19797
- var RecordColumnConfigSchema = z.object({
19798
- key: ModelIdSchema,
19799
- label: z.string().trim().min(1).max(120),
19800
- path: z.string().trim().min(1).max(500),
19801
- width: z.union([z.number().positive(), z.string().trim().min(1).max(100)]).optional(),
19802
- renderType: z.enum(["text", "badge", "datetime", "count", "json"]).optional(),
19803
- badgeColor: z.string().trim().min(1).max(40).optional()
19804
- });
19805
- var RecordColumnsConfigSchema = z.object({
19806
- company: z.array(RecordColumnConfigSchema).optional(),
19807
- contact: z.array(RecordColumnConfigSchema).optional()
19808
- }).refine((columns) => Boolean(columns.company?.length || columns.contact?.length), {
19809
- message: "recordColumns must include at least one entity column set"
19810
- });
19811
- var CredentialRequirementSchema = z.object({
19812
- key: ModelIdSchema,
19813
- provider: ModelIdSchema,
19814
- credentialType: z.enum(["api-key", "api-key-secret", "oauth", "webhook-secret"]),
19815
- label: z.string().trim().min(1).max(120),
19816
- required: z.boolean(),
19817
- selectionMode: z.enum(["single", "multiple"]).optional(),
19818
- inputPath: z.string().trim().min(1).max(500),
19819
- verifyOnRun: z.boolean().optional()
19820
- });
19821
- var ProspectingBuildTemplateStepSchema = DisplayMetadataSchema.extend({
19822
- id: ModelIdSchema,
19823
- primaryEntity: z.enum(["company", "contact"]),
19824
- outputs: z.array(z.enum(["company", "contact", "export"])).min(1),
19825
- stageKey: ModelIdSchema,
19826
- recordEntity: z.enum(["company", "contact"]).optional(),
19827
- recordsStageKey: ModelIdSchema.optional(),
19828
- recordSourceStageKey: ModelIdSchema.optional(),
19829
- dependsOn: z.array(ModelIdSchema).optional(),
19830
- dependencyMode: z.literal("per-record-eligibility"),
19831
- capabilityKey: ModelIdSchema,
19832
- defaultBatchSize: z.number().int().positive(),
19833
- maxBatchSize: z.number().int().positive(),
19834
- recordColumns: RecordColumnsConfigSchema.optional(),
19835
- credentialRequirements: z.array(CredentialRequirementSchema).optional()
19836
- }).refine((step) => step.defaultBatchSize <= step.maxBatchSize, {
19837
- message: "defaultBatchSize must be less than or equal to maxBatchSize",
19838
- path: ["defaultBatchSize"]
19839
- });
19840
- var ProspectingBuildTemplateSchema = DisplayMetadataSchema.extend({
19841
- id: ModelIdSchema,
19842
- steps: z.array(ProspectingBuildTemplateStepSchema).min(1)
19843
- });
19844
- var DTC_RECORD_COLUMNS = {
19845
- populated: {
19846
- company: [
19847
- { key: "name", label: "Company", path: "company.name" },
19848
- { key: "domain", label: "Domain", path: "company.domain" },
19849
- { key: "employee-count", label: "Employees", path: "company.numEmployees", renderType: "count" },
19850
- { key: "apollo-industry", label: "Apollo industry", path: "company.category" },
19851
- { key: "location", label: "Location", path: "company.locationState" }
19852
- ]
19853
- },
19854
- crawled: {
19855
- company: [
19856
- { key: "name", label: "Company", path: "company.name" },
19857
- { key: "domain", label: "Domain", path: "company.domain" },
19858
- { key: "page-count", label: "Pages", path: "company.enrichmentData.websiteCrawl.pageCount", renderType: "count" },
19859
- { key: "crawl-status", label: "Crawl status", path: "processingState.crawled.status", renderType: "badge" }
19860
- ]
19861
- },
19862
- extracted: {
19863
- company: [
19864
- { key: "name", label: "Company", path: "company.name" },
19865
- { key: "domain", label: "Domain", path: "company.domain" },
19866
- { key: "description", label: "Description", path: "company.enrichmentData.websiteCrawl.companyDescription" },
19867
- { key: "services", label: "Services", path: "company.enrichmentData.websiteCrawl.services", renderType: "json" },
19868
- { key: "automation-gaps", label: "Automation gaps", path: "company.enrichmentData.websiteCrawl.automationGaps", renderType: "json" },
19869
- { key: "contact-count", label: "Contacts", path: "company.enrichmentData.websiteCrawl.emailCount", renderType: "count" }
19870
- ]
19871
- },
19872
- qualified: {
19873
- company: [
19874
- { key: "name", label: "Company", path: "company.name" },
19875
- { key: "domain", label: "Domain", path: "company.domain" },
19876
- { key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
19877
- { key: "signals", label: "Signals", path: "company.qualificationSignals", renderType: "json" },
19878
- { key: "disqualified-reason", label: "Disqualified reason", path: "processingState.qualified.data.disqualifiedReason" }
19879
- ]
19880
- },
19881
- decisionMakers: {
19882
- contact: [
19883
- { key: "name", label: "Name", path: "contact.name" },
19884
- { key: "title", label: "Title", path: "contact.title" },
19885
- { key: "email", label: "Email", path: "contact.email" },
19886
- { key: "linkedin", label: "LinkedIn", path: "contact.linkedinUrl" },
19887
- { key: "priority-score", label: "Priority", path: "contact.enrichmentData.apollo.priorityScore", renderType: "badge" }
19888
- ]
19889
- },
19890
- uploaded: {
19891
- company: [
19892
- { key: "name", label: "Company", path: "company.name" },
19893
- { key: "domain", label: "Domain", path: "company.domain" },
19894
- { key: "contacts", label: "Contacts", path: "company.enrichmentData.approvedLeadListExport.contacts", renderType: "json" },
19895
- { key: "score", label: "Score", path: "company.qualificationScore", renderType: "badge", badgeColor: "green" },
19896
- { key: "approval", label: "Approval", path: "company.enrichmentData.approvedLeadListExport.approvalStatus", renderType: "badge" }
19897
- ]
19898
- }
19899
- };
20134
+ var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]).meta({ label: "Surface type", color: "blue" });
19900
20135
  z.object({
19901
- id: ModelIdSchema,
19902
- label: z.string(),
19903
- description: z.string(),
19904
- resourceId: ModelIdSchema
19905
- });
19906
- var PROSPECTING_STEPS = {
19907
- localServices: {
19908
- sourceCompanies: {
19909
- id: "source-companies",
19910
- label: "Companies found",
19911
- primaryEntity: "company",
19912
- outputs: ["company"],
19913
- stageKey: "populated",
19914
- dependencyMode: "per-record-eligibility",
19915
- capabilityKey: "lead-gen.company.source",
19916
- defaultBatchSize: 100,
19917
- maxBatchSize: 250
19918
- },
19919
- analyzeWebsites: {
19920
- id: "analyze-websites",
19921
- label: "Websites analyzed",
19922
- primaryEntity: "company",
19923
- outputs: ["company"],
19924
- stageKey: "extracted",
19925
- dependsOn: ["source-companies"],
19926
- dependencyMode: "per-record-eligibility",
19927
- capabilityKey: "lead-gen.company.website-extract",
19928
- defaultBatchSize: 50,
19929
- maxBatchSize: 100
19930
- },
19931
- qualifyCompanies: {
19932
- id: "qualify-companies",
19933
- label: "Companies qualified",
19934
- primaryEntity: "company",
19935
- outputs: ["company"],
19936
- stageKey: "qualified",
19937
- dependsOn: ["analyze-websites"],
19938
- dependencyMode: "per-record-eligibility",
19939
- capabilityKey: "lead-gen.company.qualify",
19940
- defaultBatchSize: 100,
19941
- maxBatchSize: 250
19942
- },
19943
- findContacts: {
19944
- id: "find-contacts",
19945
- label: "Decision-makers found",
19946
- primaryEntity: "contact",
19947
- outputs: ["contact"],
19948
- stageKey: "discovered",
19949
- dependsOn: ["qualify-companies"],
19950
- dependencyMode: "per-record-eligibility",
19951
- capabilityKey: "lead-gen.contact.discover",
19952
- defaultBatchSize: 50,
19953
- maxBatchSize: 100
19954
- },
19955
- verifyEmails: {
19956
- id: "verify-emails",
19957
- label: "Emails verified",
19958
- primaryEntity: "contact",
19959
- outputs: ["contact"],
19960
- stageKey: "verified",
19961
- dependsOn: ["find-contacts"],
19962
- dependencyMode: "per-record-eligibility",
19963
- capabilityKey: "lead-gen.contact.verify-email",
19964
- defaultBatchSize: 100,
19965
- maxBatchSize: 500
19966
- },
19967
- personalize: {
19968
- id: "personalize",
19969
- label: "Personalize",
19970
- primaryEntity: "contact",
19971
- outputs: ["contact"],
19972
- stageKey: "personalized",
19973
- dependsOn: ["verify-emails"],
19974
- dependencyMode: "per-record-eligibility",
19975
- capabilityKey: "lead-gen.contact.personalize",
19976
- defaultBatchSize: 25,
19977
- maxBatchSize: 100
19978
- },
19979
- review: {
19980
- id: "review",
19981
- label: "Reviewed and exported",
19982
- primaryEntity: "contact",
19983
- outputs: ["export"],
19984
- stageKey: "uploaded",
19985
- dependsOn: ["personalize"],
19986
- dependencyMode: "per-record-eligibility",
19987
- capabilityKey: "lead-gen.review.outreach-ready",
19988
- defaultBatchSize: 25,
19989
- maxBatchSize: 100
19990
- }
19991
- },
19992
- dtcApolloClickup: {
19993
- importApolloSearch: {
19994
- id: "import-apollo-search",
19995
- label: "Companies found",
19996
- description: "Pull companies and seed contact data from a predefined Apollo search or list.",
19997
- primaryEntity: "company",
19998
- outputs: ["company", "contact"],
19999
- stageKey: "populated",
20000
- dependencyMode: "per-record-eligibility",
20001
- capabilityKey: "lead-gen.company.apollo-import",
20002
- defaultBatchSize: 250,
20003
- maxBatchSize: 1e3,
20004
- recordColumns: DTC_RECORD_COLUMNS.populated,
20005
- credentialRequirements: [
20006
- {
20007
- key: "apollo",
20008
- provider: "apollo",
20009
- credentialType: "api-key-secret",
20010
- label: "Apollo API key",
20011
- required: true,
20012
- selectionMode: "single",
20013
- inputPath: "credential"
20014
- }
20015
- ]
20016
- },
20017
- apifyCrawl: {
20018
- id: "apify-crawl",
20019
- label: "Websites crawled",
20020
- description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis. Overwrites the synthetic seed Apollo Import wrote with real page content.",
20021
- primaryEntity: "company",
20022
- outputs: ["company"],
20023
- stageKey: "crawled",
20024
- dependsOn: ["import-apollo-search"],
20025
- dependencyMode: "per-record-eligibility",
20026
- capabilityKey: "lead-gen.company.apify-crawl",
20027
- defaultBatchSize: 50,
20028
- maxBatchSize: 100,
20029
- recordColumns: DTC_RECORD_COLUMNS.crawled,
20030
- credentialRequirements: [
20031
- {
20032
- key: "apify",
20033
- provider: "apify",
20034
- credentialType: "api-key-secret",
20035
- label: "Apify API token",
20036
- required: true,
20037
- selectionMode: "single",
20038
- inputPath: "credential",
20039
- verifyOnRun: true
20040
- }
20041
- ]
20042
- },
20043
- analyzeWebsites: {
20044
- id: "analyze-websites",
20045
- label: "Websites analyzed",
20046
- description: "Extract subscription, product, retention, and tech-stack signals from each brand website.",
20047
- primaryEntity: "company",
20048
- outputs: ["company"],
20049
- stageKey: "extracted",
20050
- dependsOn: ["apify-crawl"],
20051
- dependencyMode: "per-record-eligibility",
20052
- capabilityKey: "lead-gen.company.website-extract",
20053
- defaultBatchSize: 50,
20054
- maxBatchSize: 100,
20055
- recordColumns: DTC_RECORD_COLUMNS.extracted
20056
- },
20057
- scoreDtcFit: {
20058
- id: "score-dtc-fit",
20059
- label: "Companies qualified",
20060
- description: "Classify subscription potential, consumable-product fit, retention maturity, and disqualifiers.",
20061
- primaryEntity: "company",
20062
- outputs: ["company"],
20063
- stageKey: "qualified",
20064
- dependsOn: ["analyze-websites"],
20065
- dependencyMode: "per-record-eligibility",
20066
- capabilityKey: "lead-gen.company.dtc-subscription-qualify",
20067
- defaultBatchSize: 100,
20068
- maxBatchSize: 250,
20069
- recordColumns: DTC_RECORD_COLUMNS.qualified
20070
- },
20071
- enrichDecisionMakers: {
20072
- id: "enrich-decision-makers",
20073
- label: "Decision-makers found",
20074
- description: "Use Apollo to find qualified contacts at qualified companies - founders, retention leads, lifecycle leads, and marketing owners.",
20075
- primaryEntity: "company",
20076
- outputs: ["contact"],
20077
- stageKey: "decision-makers-enriched",
20078
- recordEntity: "contact",
20079
- dependsOn: ["score-dtc-fit"],
20080
- dependencyMode: "per-record-eligibility",
20081
- capabilityKey: "lead-gen.contact.apollo-decision-maker-enrich",
20082
- defaultBatchSize: 100,
20083
- maxBatchSize: 250,
20084
- recordColumns: DTC_RECORD_COLUMNS.decisionMakers,
20085
- credentialRequirements: [
20086
- {
20087
- key: "apollo",
20088
- provider: "apollo",
20089
- credentialType: "api-key-secret",
20090
- label: "Apollo API key",
20091
- required: true,
20092
- selectionMode: "single",
20093
- inputPath: "credential"
20094
- }
20095
- ]
20096
- },
20097
- reviewAndExport: {
20098
- id: "review-and-export",
20099
- label: "Reviewed and exported",
20100
- description: "Operator QC approves or rejects qualified companies, then approved records are exported as a lead list with unverified emails.",
20101
- primaryEntity: "company",
20102
- outputs: ["export"],
20103
- stageKey: "uploaded",
20104
- recordsStageKey: "uploaded",
20105
- recordSourceStageKey: "qualified",
20106
- dependsOn: ["enrich-decision-makers"],
20107
- dependencyMode: "per-record-eligibility",
20108
- capabilityKey: "lead-gen.export.list",
20109
- defaultBatchSize: 100,
20110
- maxBatchSize: 250,
20111
- recordColumns: DTC_RECORD_COLUMNS.uploaded,
20112
- credentialRequirements: [
20113
- {
20114
- key: "clickup",
20115
- provider: "clickup",
20116
- credentialType: "api-key-secret",
20117
- label: "ClickUp API token",
20118
- required: true,
20119
- selectionMode: "single",
20120
- inputPath: "clickupCredential",
20121
- verifyOnRun: true
20122
- }
20123
- ]
20124
- }
20125
- }
20126
- };
20127
- var OrganizationModelProspectingSchema = z.object({
20128
- listEntityId: ModelIdSchema,
20129
- companyEntityId: ModelIdSchema,
20130
- contactEntityId: ModelIdSchema,
20131
- description: DescriptionSchema.optional(),
20132
- companyStages: z.array(ProspectingLifecycleStageSchema).min(1),
20133
- contactStages: z.array(ProspectingLifecycleStageSchema).min(1),
20134
- defaultBuildTemplateId: ModelIdSchema,
20135
- buildTemplates: z.array(ProspectingBuildTemplateSchema).min(1)
20136
- });
20137
- function toProspectingLifecycleStage(stage) {
20138
- return {
20139
- id: stage.key,
20140
- label: stage.label,
20141
- order: stage.order
20142
- };
20143
- }
20144
- function leadGenStagesForEntity(entity) {
20145
- return Object.values(LEAD_GEN_STAGE_CATALOG).filter((stage) => stage.entity === entity || stage.additionalEntities?.includes(entity)).sort((a3, b2) => a3.order - b2.order).map(toProspectingLifecycleStage);
20146
- }
20147
- var DEFAULT_ORGANIZATION_MODEL_PROSPECTING = {
20148
- listEntityId: "leadgen.list",
20149
- companyEntityId: "leadgen.company",
20150
- contactEntityId: "leadgen.contact",
20151
- companyStages: leadGenStagesForEntity("company"),
20152
- contactStages: leadGenStagesForEntity("contact"),
20153
- defaultBuildTemplateId: "local-services",
20154
- buildTemplates: [
20155
- {
20156
- id: "local-services",
20157
- label: "Local Services Prospecting",
20158
- description: "Curated local-services list build using company sourcing, website analysis, qualification, contact discovery, verification, personalization, and review.",
20159
- steps: [
20160
- PROSPECTING_STEPS.localServices.sourceCompanies,
20161
- PROSPECTING_STEPS.localServices.analyzeWebsites,
20162
- PROSPECTING_STEPS.localServices.qualifyCompanies,
20163
- PROSPECTING_STEPS.localServices.findContacts,
20164
- PROSPECTING_STEPS.localServices.verifyEmails,
20165
- PROSPECTING_STEPS.localServices.personalize,
20166
- PROSPECTING_STEPS.localServices.review
20167
- ]
20168
- },
20169
- {
20170
- id: "dtc-subscription-apollo-clickup",
20171
- label: "DTC Subscription Apollo Export",
20172
- description: "Prospecting pipeline for DTC subscription or subscription-ready brands where Apollo is the source and contact-enrichment layer, Elevasis handles company research and fit scoring, and approved leads export as an approved lead list.",
20173
- steps: [
20174
- PROSPECTING_STEPS.dtcApolloClickup.importApolloSearch,
20175
- PROSPECTING_STEPS.dtcApolloClickup.apifyCrawl,
20176
- PROSPECTING_STEPS.dtcApolloClickup.analyzeWebsites,
20177
- PROSPECTING_STEPS.dtcApolloClickup.scoreDtcFit,
20178
- PROSPECTING_STEPS.dtcApolloClickup.enrichDecisionMakers,
20179
- PROSPECTING_STEPS.dtcApolloClickup.reviewAndExport
20180
- ]
20181
- }
20182
- ]
20183
- };
20184
- var SurfaceTypeSchema = z.enum(["page", "dashboard", "graph", "detail", "list", "settings"]);
20185
- var SurfaceDefinitionSchema = z.object({
20186
20136
  id: ModelIdSchema,
20187
20137
  label: LabelSchema,
20188
20138
  path: PathSchema,
@@ -20191,23 +20141,55 @@ var SurfaceDefinitionSchema = z.object({
20191
20141
  enabled: z.boolean().default(true),
20192
20142
  devOnly: z.boolean().optional(),
20193
20143
  icon: IconNameSchema.optional(),
20194
- featureId: ModelIdSchema.optional(),
20195
- featureIds: ReferenceIdsSchema,
20196
- entityIds: ReferenceIdsSchema,
20197
- resourceIds: ReferenceIdsSchema,
20198
- capabilityIds: ReferenceIdsSchema,
20199
- parentId: ModelIdSchema.optional()
20144
+ systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
20145
+ entityIds: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]),
20146
+ resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
20147
+ actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
20148
+ parentId: ModelIdSchema.meta({ ref: "surface" }).optional()
20200
20149
  });
20201
- var NavigationGroupSchema = z.object({
20150
+ var SidebarSurfaceTargetsSchema = z.object({
20151
+ systems: z.array(ModelIdSchema.meta({ ref: "system" })).default([]).optional(),
20152
+ entities: z.array(ModelIdSchema.meta({ ref: "entity" })).default([]).optional(),
20153
+ resources: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]).optional(),
20154
+ actions: z.array(ModelIdSchema.meta({ ref: "action" })).default([]).optional()
20155
+ }).default({});
20156
+ var SidebarNodeSchema = z.lazy(
20157
+ () => z.discriminatedUnion("type", [
20158
+ z.object({
20159
+ type: z.literal("group"),
20160
+ label: LabelSchema,
20161
+ description: DescriptionSchema.optional(),
20162
+ icon: IconNameSchema.optional(),
20163
+ order: z.number().int().optional(),
20164
+ children: z.record(z.string(), SidebarNodeSchema).default({})
20165
+ }),
20166
+ z.object({
20167
+ type: z.literal("surface"),
20168
+ label: LabelSchema,
20169
+ path: PathSchema,
20170
+ surfaceType: SurfaceTypeSchema,
20171
+ description: DescriptionSchema.optional(),
20172
+ icon: IconNameSchema.optional(),
20173
+ order: z.number().int().optional(),
20174
+ targets: SidebarSurfaceTargetsSchema.optional(),
20175
+ devOnly: z.boolean().optional(),
20176
+ requiresAdmin: z.boolean().optional()
20177
+ })
20178
+ ])
20179
+ );
20180
+ var SidebarSectionSchema = z.record(z.string(), SidebarNodeSchema).default({});
20181
+ var SidebarNavigationSchema = z.object({
20182
+ primary: SidebarSectionSchema,
20183
+ bottom: SidebarSectionSchema
20184
+ }).default({ primary: {}, bottom: {} });
20185
+ var OrganizationModelNavigationSchema = z.object({
20186
+ sidebar: SidebarNavigationSchema
20187
+ }).default({ sidebar: { primary: {}, bottom: {} } });
20188
+ z.object({
20202
20189
  id: ModelIdSchema,
20203
20190
  label: LabelSchema,
20204
20191
  placement: z.string().trim().min(1).max(50),
20205
- surfaceIds: z.array(ModelIdSchema).default([])
20206
- });
20207
- var OrganizationModelNavigationSchema = z.object({
20208
- defaultSurfaceId: ModelIdSchema.optional(),
20209
- surfaces: z.array(SurfaceDefinitionSchema).default([]),
20210
- groups: z.array(NavigationGroupSchema).default([])
20192
+ surfaceIds: z.array(ModelIdSchema.meta({ ref: "surface" })).default([])
20211
20193
  });
20212
20194
  var BusinessHoursDaySchema = z.object({
20213
20195
  open: z.string().trim().regex(/^\d{2}:\d{2}$/, "Expected HH:MM format"),
@@ -20292,6 +20274,8 @@ var FirmographicsSchema = z.object({
20292
20274
  var CustomerSegmentSchema = z.object({
20293
20275
  /** Stable unique identifier for the segment (e.g. "segment-smb-agencies"). */
20294
20276
  id: z.string().trim().min(1).max(100),
20277
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20278
+ order: z.number(),
20295
20279
  /** Human-readable name shown to agents and in UI (e.g. "SMB Marketing Agencies"). */
20296
20280
  name: z.string().trim().max(200).default(""),
20297
20281
  /** One or two sentences describing who this segment is. */
@@ -20319,16 +20303,16 @@ var CustomerSegmentSchema = z.object({
20319
20303
  */
20320
20304
  valueProp: z.string().trim().max(2e3).default("")
20321
20305
  });
20322
- var CustomersDomainSchema = z.object({
20323
- segments: z.array(CustomerSegmentSchema).default([])
20324
- });
20325
- var DEFAULT_ORGANIZATION_MODEL_CUSTOMERS = {
20326
- segments: []
20327
- };
20328
- var PricingModelSchema = z.enum(["one-time", "subscription", "usage-based", "custom"]);
20306
+ var CustomersDomainSchema = z.record(z.string(), CustomerSegmentSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
20307
+ message: "Each segment entry id must match its map key"
20308
+ }).default({});
20309
+ var DEFAULT_ORGANIZATION_MODEL_CUSTOMERS = {};
20310
+ var PricingModelSchema = z.enum(["one-time", "subscription", "usage-based", "custom"]).meta({ label: "Pricing model", color: "green" });
20329
20311
  var ProductSchema = z.object({
20330
20312
  /** Stable unique identifier for the product (e.g. "product-starter-plan"). */
20331
20313
  id: z.string().trim().min(1).max(100),
20314
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20315
+ order: z.number(),
20332
20316
  /** Human-readable name shown to agents and in UI (e.g. "Starter Plan"). */
20333
20317
  name: z.string().trim().max(200).default(""),
20334
20318
  /** One or two sentences describing what this product/service delivers. */
@@ -20355,88 +20339,634 @@ var ProductSchema = z.object({
20355
20339
  */
20356
20340
  targetSegmentIds: z.array(z.string().trim().min(1)).default([]),
20357
20341
  /**
20358
- * Optional: ID of the platform feature responsible for delivering this product.
20359
- * When present, must reference a declared `features[].id`.
20342
+ * Optional: ID of the platform system responsible for delivering this product.
20343
+ * When present, must reference a declared `systems.systems[].id`.
20360
20344
  * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
20361
20345
  */
20362
20346
  deliveryFeatureId: z.string().trim().min(1).optional()
20363
20347
  });
20364
- var OfferingsDomainSchema = z.object({
20365
- products: z.array(ProductSchema).default([])
20348
+ var OfferingsDomainSchema = z.record(z.string(), ProductSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
20349
+ message: "Each product entry id must match its map key"
20350
+ }).default({});
20351
+ var DEFAULT_ORGANIZATION_MODEL_OFFERINGS = {};
20352
+ var EntityIdSchema = ModelIdSchema;
20353
+ var EntityLinkKindSchema = z.enum(["belongs-to", "has-many", "has-one", "many-to-many"]).meta({ label: "Link kind" });
20354
+ var EntityLinkSchema = z.object({
20355
+ toEntity: EntityIdSchema.meta({ ref: "entity" }),
20356
+ kind: EntityLinkKindSchema,
20357
+ via: z.string().trim().min(1).max(255).optional(),
20358
+ label: LabelSchema.optional()
20359
+ });
20360
+ var EntitySchema = z.object({
20361
+ id: EntityIdSchema,
20362
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20363
+ order: z.number(),
20364
+ label: LabelSchema,
20365
+ description: DescriptionSchema.optional(),
20366
+ ownedBySystemId: ModelIdSchema.meta({ ref: "system" }),
20367
+ table: z.string().trim().min(1).max(255).optional(),
20368
+ rowSchema: ModelIdSchema.optional(),
20369
+ stateCatalogId: ModelIdSchema.optional(),
20370
+ links: z.array(EntityLinkSchema).optional()
20366
20371
  });
20367
- var DEFAULT_ORGANIZATION_MODEL_OFFERINGS = {
20368
- products: []
20372
+ var EntitiesDomainSchema = z.record(z.string(), EntitySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
20373
+ message: "Each entity entry id must match its map key"
20374
+ }).default({});
20375
+ var ENTITY_ENTRY_INPUTS = [
20376
+ {
20377
+ id: "crm.deal",
20378
+ order: 10,
20379
+ label: "Deal",
20380
+ description: "A CRM opportunity or sales pipeline record.",
20381
+ ownedBySystemId: "sales.crm",
20382
+ table: "crm_deals",
20383
+ stateCatalogId: "crm.pipeline",
20384
+ links: [{ toEntity: "crm.contact", kind: "has-many", via: "deal_contacts", label: "contacts" }]
20385
+ },
20386
+ {
20387
+ id: "crm.contact",
20388
+ order: 20,
20389
+ label: "CRM Contact",
20390
+ description: "A person associated with a CRM relationship or deal.",
20391
+ ownedBySystemId: "sales.crm",
20392
+ table: "crm_contacts"
20393
+ },
20394
+ {
20395
+ id: "leadgen.list",
20396
+ order: 30,
20397
+ label: "Lead List",
20398
+ description: "A prospecting list that groups companies and contacts for acquisition workflows.",
20399
+ ownedBySystemId: "sales.lead-gen",
20400
+ table: "acq_lists",
20401
+ links: [
20402
+ { toEntity: "leadgen.company", kind: "has-many", via: "acq_list_companies", label: "companies" },
20403
+ { toEntity: "leadgen.contact", kind: "has-many", via: "acq_list_members", label: "contacts" }
20404
+ ]
20405
+ },
20406
+ {
20407
+ id: "leadgen.company",
20408
+ order: 40,
20409
+ label: "Lead Company",
20410
+ description: "A company record sourced, enriched, and qualified during prospecting.",
20411
+ ownedBySystemId: "sales.lead-gen",
20412
+ table: "acq_list_companies",
20413
+ stateCatalogId: "lead-gen.company",
20414
+ links: [
20415
+ { toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
20416
+ { toEntity: "leadgen.contact", kind: "has-many", via: "company_id", label: "contacts" }
20417
+ ]
20418
+ },
20419
+ {
20420
+ id: "leadgen.contact",
20421
+ order: 50,
20422
+ label: "Lead Contact",
20423
+ description: "A prospect contact discovered or enriched during lead generation.",
20424
+ ownedBySystemId: "sales.lead-gen",
20425
+ table: "acq_list_members",
20426
+ stateCatalogId: "lead-gen.contact",
20427
+ links: [
20428
+ { toEntity: "leadgen.list", kind: "belongs-to", via: "list_id", label: "list" },
20429
+ { toEntity: "leadgen.company", kind: "belongs-to", via: "company_id", label: "company" }
20430
+ ]
20431
+ },
20432
+ {
20433
+ id: "delivery.project",
20434
+ order: 60,
20435
+ label: "Project",
20436
+ description: "A client delivery project.",
20437
+ ownedBySystemId: "projects",
20438
+ table: "projects",
20439
+ links: [
20440
+ { toEntity: "delivery.milestone", kind: "has-many", via: "project_id", label: "milestones" },
20441
+ { toEntity: "delivery.task", kind: "has-many", via: "project_id", label: "tasks" }
20442
+ ]
20443
+ },
20444
+ {
20445
+ id: "delivery.milestone",
20446
+ order: 70,
20447
+ label: "Milestone",
20448
+ description: "A delivery checkpoint within a project.",
20449
+ ownedBySystemId: "projects",
20450
+ table: "project_milestones",
20451
+ links: [
20452
+ { toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
20453
+ { toEntity: "delivery.task", kind: "has-many", via: "milestone_id", label: "tasks" }
20454
+ ]
20455
+ },
20456
+ {
20457
+ id: "delivery.task",
20458
+ order: 80,
20459
+ label: "Task",
20460
+ description: "A delivery task that can move through the task status catalog.",
20461
+ ownedBySystemId: "projects",
20462
+ table: "project_tasks",
20463
+ stateCatalogId: "delivery.task",
20464
+ links: [
20465
+ { toEntity: "delivery.project", kind: "belongs-to", via: "project_id", label: "project" },
20466
+ { toEntity: "delivery.milestone", kind: "belongs-to", via: "milestone_id", label: "milestone" }
20467
+ ]
20468
+ }
20469
+ ];
20470
+ var DEFAULT_ORGANIZATION_MODEL_ENTITIES = Object.fromEntries(
20471
+ ENTITY_ENTRY_INPUTS.map((entity) => {
20472
+ const parsed = EntitySchema.parse(entity);
20473
+ return [parsed.id, parsed];
20474
+ })
20475
+ );
20476
+
20477
+ // src/organization-model/domains/actions.ts
20478
+ var ActionResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
20479
+ z.enum(["slash-command", "mcp-tool", "api-endpoint", "script-execution"]).meta({ label: "Invocation kind" });
20480
+ var ActionIdSchema = ModelIdSchema;
20481
+ var ActionScopeSchema = z.union([
20482
+ z.literal("global"),
20483
+ z.object({
20484
+ domain: ModelIdSchema
20485
+ })
20486
+ ]);
20487
+ var ActionRefSchema = z.object({
20488
+ actionId: ActionIdSchema.meta({ ref: "action" }),
20489
+ intent: z.enum(["exposes", "consumes"]).meta({ label: "Intent" })
20490
+ });
20491
+ var SlashCommandInvocationSchema = z.object({
20492
+ kind: z.literal("slash-command"),
20493
+ command: z.string().trim().min(1).max(200).regex(/^\/[^\s].*$/, "Slash commands must start with /"),
20494
+ toolFactory: ModelIdSchema.optional()
20495
+ });
20496
+ var McpToolInvocationSchema = z.object({
20497
+ kind: z.literal("mcp-tool"),
20498
+ server: ModelIdSchema,
20499
+ name: ModelIdSchema
20500
+ });
20501
+ var ApiEndpointInvocationSchema = z.object({
20502
+ kind: z.literal("api-endpoint"),
20503
+ method: z.enum(["GET", "POST", "PATCH", "DELETE"]).meta({ label: "HTTP method" }),
20504
+ path: z.string().trim().startsWith("/").max(500),
20505
+ requestSchema: ModelIdSchema.optional(),
20506
+ responseSchema: ModelIdSchema.optional()
20507
+ });
20508
+ var ScriptExecutionInvocationSchema = z.object({
20509
+ kind: z.literal("script-execution"),
20510
+ resourceId: ActionResourceIdSchema
20511
+ });
20512
+ var ActionInvocationSchema = z.discriminatedUnion("kind", [
20513
+ SlashCommandInvocationSchema,
20514
+ McpToolInvocationSchema,
20515
+ ApiEndpointInvocationSchema,
20516
+ ScriptExecutionInvocationSchema
20517
+ ]);
20518
+ var ActionSchema = z.object({
20519
+ id: ActionIdSchema,
20520
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20521
+ order: z.number(),
20522
+ label: LabelSchema,
20523
+ description: DescriptionSchema.optional(),
20524
+ scope: ActionScopeSchema.default("global"),
20525
+ resourceId: ActionResourceIdSchema.optional(),
20526
+ affects: z.array(EntityIdSchema.meta({ ref: "entity" })).optional(),
20527
+ invocations: z.array(ActionInvocationSchema).default([]),
20528
+ knowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
20529
+ lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
20530
+ });
20531
+ var ActionsDomainSchema = z.record(z.string(), ActionSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
20532
+ message: "Each action entry id must match its map key"
20533
+ }).default({});
20534
+ var LEAD_GEN_ACTION_ENTRY_INPUTS = [
20535
+ {
20536
+ id: "lead-gen.company.source",
20537
+ order: 10,
20538
+ label: "Source companies",
20539
+ description: "Import source companies from a list provider.",
20540
+ scope: { domain: "sales" },
20541
+ resourceId: "lgn-import-workflow",
20542
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/source" }]
20543
+ },
20544
+ {
20545
+ id: "lead-gen.company.apollo-import",
20546
+ order: 20,
20547
+ label: "Import from Apollo",
20548
+ description: "Pull companies and seed contact data from an Apollo search or list.",
20549
+ scope: { domain: "sales" },
20550
+ resourceId: "lgn-01c-apollo-import-workflow",
20551
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/apollo-import" }]
20552
+ },
20553
+ {
20554
+ id: "lead-gen.contact.discover",
20555
+ order: 30,
20556
+ label: "Discover contact emails",
20557
+ description: "Find email addresses for contacts at qualified companies.",
20558
+ scope: { domain: "sales" },
20559
+ resourceId: "lgn-04-email-discovery-workflow",
20560
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/discover" }]
20561
+ },
20562
+ {
20563
+ id: "lead-gen.contact.verify-email",
20564
+ order: 40,
20565
+ label: "Verify emails",
20566
+ description: "Check email deliverability before outreach.",
20567
+ scope: { domain: "sales" },
20568
+ resourceId: "lgn-05-email-verification-workflow",
20569
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/verify-email" }]
20570
+ },
20571
+ {
20572
+ id: "lead-gen.company.apify-crawl",
20573
+ order: 50,
20574
+ label: "Crawl websites",
20575
+ description: "Crawl company websites via Apify and store raw page markdown in enrichmentData.websiteCrawl.pages for downstream LLM analysis.",
20576
+ scope: { domain: "sales" },
20577
+ resourceId: "lgn-02a-apify-website-crawl-workflow",
20578
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/apify-crawl" }]
20579
+ },
20580
+ {
20581
+ id: "lead-gen.company.website-extract",
20582
+ order: 60,
20583
+ label: "Extract website signals",
20584
+ description: "Scrape and analyze company websites for qualification signals.",
20585
+ scope: { domain: "sales" },
20586
+ resourceId: "lgn-02-website-extract-workflow",
20587
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/website-extract" }]
20588
+ },
20589
+ {
20590
+ id: "lead-gen.company.qualify",
20591
+ order: 70,
20592
+ label: "Qualify companies",
20593
+ description: "Score and filter companies against the ICP rubric.",
20594
+ scope: { domain: "sales" },
20595
+ resourceId: "lgn-03-company-qualification-workflow",
20596
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/qualify" }]
20597
+ },
20598
+ {
20599
+ id: "lead-gen.company.dtc-subscription-qualify",
20600
+ order: 80,
20601
+ label: "Qualify DTC subscription fit",
20602
+ description: "Classify subscription potential and consumable-product fit for DTC brands.",
20603
+ scope: { domain: "sales" },
20604
+ resourceId: "lgn-03b-dtc-subscription-score-workflow",
20605
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/dtc-subscription-qualify" }]
20606
+ },
20607
+ {
20608
+ id: "lead-gen.contact.apollo-decision-maker-enrich",
20609
+ order: 90,
20610
+ label: "Enrich decision-makers",
20611
+ description: "Find and enrich qualified contacts at qualified companies via Apollo.",
20612
+ scope: { domain: "sales" },
20613
+ resourceId: "lgn-04b-apollo-decision-maker-enrich-workflow",
20614
+ invocations: [
20615
+ { kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/apollo-decision-maker-enrich" }
20616
+ ]
20617
+ },
20618
+ {
20619
+ id: "lead-gen.contact.personalize",
20620
+ order: 100,
20621
+ label: "Personalize outreach",
20622
+ description: "Generate personalized opening lines for each contact.",
20623
+ scope: { domain: "sales" },
20624
+ resourceId: "ist-personalization-workflow",
20625
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/contacts/personalize" }]
20626
+ },
20627
+ {
20628
+ id: "lead-gen.review.outreach-ready",
20629
+ order: 110,
20630
+ label: "Upload to outreach",
20631
+ description: "Upload approved contacts to the outreach sequence after QC review.",
20632
+ scope: { domain: "sales" },
20633
+ resourceId: "ist-upload-contacts-workflow",
20634
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/review/outreach-ready" }]
20635
+ },
20636
+ {
20637
+ id: "lead-gen.export.list",
20638
+ order: 120,
20639
+ label: "Export lead list",
20640
+ description: "Export approved leads as a downloadable lead list.",
20641
+ scope: { domain: "sales" },
20642
+ resourceId: "lgn-06-export-list-workflow",
20643
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/export/list" }]
20644
+ },
20645
+ {
20646
+ id: "lead-gen.company.cleanup",
20647
+ order: 130,
20648
+ label: "Clean up companies",
20649
+ description: "Remove disqualified or duplicate companies from the list.",
20650
+ scope: { domain: "sales" },
20651
+ resourceId: "lgn-company-cleanup-workflow",
20652
+ invocations: [{ kind: "api-endpoint", method: "POST", path: "/api/prospecting/companies/cleanup" }]
20653
+ }
20654
+ ];
20655
+ var LEAD_GEN_ACTION_ENTRIES = Object.fromEntries(
20656
+ LEAD_GEN_ACTION_ENTRY_INPUTS.map((action) => {
20657
+ const parsed = ActionSchema.parse(action);
20658
+ return [parsed.id, parsed];
20659
+ })
20660
+ );
20661
+ var CRM_ACTION_ENTRY_INPUTS = [
20662
+ {
20663
+ id: "send_reply",
20664
+ order: 210,
20665
+ label: "Send Reply",
20666
+ description: "Send a contextual reply for an active CRM deal.",
20667
+ scope: { domain: "sales" },
20668
+ resourceId: "crm-send-reply-workflow",
20669
+ affects: ["crm.deal"]
20670
+ },
20671
+ {
20672
+ id: "send_link",
20673
+ order: 220,
20674
+ label: "Send Booking Link",
20675
+ description: "Send a booking link to move a deal toward a scheduled call.",
20676
+ scope: { domain: "sales" },
20677
+ resourceId: "crm-send-booking-link-workflow",
20678
+ affects: ["crm.deal"]
20679
+ },
20680
+ {
20681
+ id: "send_nudge",
20682
+ order: 230,
20683
+ label: "Send Nudge",
20684
+ description: "Send a follow-up nudge for a stalled CRM deal.",
20685
+ scope: { domain: "sales" },
20686
+ resourceId: "crm-send-nudge-workflow",
20687
+ affects: ["crm.deal"]
20688
+ },
20689
+ {
20690
+ id: "rebook",
20691
+ order: 240,
20692
+ label: "Rebook",
20693
+ description: "Rebook a missed or rescheduled CRM appointment.",
20694
+ scope: { domain: "sales" },
20695
+ resourceId: "crm-rebook-workflow",
20696
+ affects: ["crm.deal"]
20697
+ },
20698
+ {
20699
+ id: "move_to_proposal",
20700
+ order: 250,
20701
+ label: "Move to Proposal",
20702
+ description: "Advance a qualified CRM deal into the proposal stage.",
20703
+ scope: { domain: "sales" },
20704
+ resourceId: "move_to_proposal-workflow",
20705
+ affects: ["crm.deal"]
20706
+ },
20707
+ {
20708
+ id: "move_to_closing",
20709
+ order: 260,
20710
+ label: "Move to Closing",
20711
+ description: "Advance a proposal-stage CRM deal into closing.",
20712
+ scope: { domain: "sales" },
20713
+ resourceId: "move_to_closing-workflow",
20714
+ affects: ["crm.deal"]
20715
+ },
20716
+ {
20717
+ id: "move_to_closed_won",
20718
+ order: 270,
20719
+ label: "Close Won",
20720
+ description: "Mark a CRM deal as closed won.",
20721
+ scope: { domain: "sales" },
20722
+ resourceId: "move_to_closed_won-workflow",
20723
+ affects: ["crm.deal"]
20724
+ },
20725
+ {
20726
+ id: "move_to_closed_lost",
20727
+ order: 280,
20728
+ label: "Close Lost",
20729
+ description: "Mark a CRM deal as closed lost.",
20730
+ scope: { domain: "sales" },
20731
+ resourceId: "move_to_closed_lost-workflow",
20732
+ affects: ["crm.deal"]
20733
+ },
20734
+ {
20735
+ id: "move_to_nurturing",
20736
+ order: 290,
20737
+ label: "Move to Nurturing",
20738
+ description: "Move a CRM deal into nurturing for future follow-up.",
20739
+ scope: { domain: "sales" },
20740
+ resourceId: "move_to_nurturing-workflow",
20741
+ affects: ["crm.deal"]
20742
+ }
20743
+ ];
20744
+ var CRM_ACTION_ENTRIES = Object.fromEntries(
20745
+ CRM_ACTION_ENTRY_INPUTS.map((action) => {
20746
+ const parsed = ActionSchema.parse(action);
20747
+ return [parsed.id, parsed];
20748
+ })
20749
+ );
20750
+ var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {
20751
+ ...LEAD_GEN_ACTION_ENTRIES,
20752
+ ...CRM_ACTION_ENTRIES
20369
20753
  };
20370
- var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]);
20371
- var SystemStatusSchema = z.enum(["active", "deprecated", "archived"]);
20754
+
20755
+ // src/organization-model/domains/systems.ts
20756
+ var SystemKindSchema = z.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
20757
+ var SystemLifecycleSchema = z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" });
20758
+ var SystemStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Status", color: "teal" });
20372
20759
  var SystemIdSchema = ModelIdSchema;
20760
+ var SystemPathSchema = z.string().trim().min(1).regex(
20761
+ /^[a-z0-9][a-z0-9-]*(?:\.[a-z0-9][a-z0-9-]*)*$/,
20762
+ 'must be a dotted lowercase path (e.g. "sales.lead-gen" or "sales.crm")'
20763
+ );
20764
+ var UiPositionSchema = z.enum(["sidebar-primary", "sidebar-bottom"]).meta({ label: "UI position" });
20765
+ var NodeIdStringSchema = z.string().trim().min(1).max(200).regex(
20766
+ /^[a-z][a-z-]*:([a-z0-9-]+)(\.[a-z0-9-]+)*(:[a-z0-9.-]+)*$/,
20767
+ "Node references must use kind:dotted-path (e.g. system:sales.crm or content-node:sales.crm:pipeline-id)"
20768
+ );
20769
+ var SystemUiSchema = z.object({
20770
+ path: PathSchema,
20771
+ surfaces: ReferenceIdsSchema,
20772
+ icon: IconNameSchema.optional(),
20773
+ order: z.number().int().optional()
20774
+ });
20775
+ var JsonValueSchema = z.lazy(
20776
+ () => z.union([
20777
+ z.string(),
20778
+ z.number(),
20779
+ z.boolean(),
20780
+ z.null(),
20781
+ z.array(JsonValueSchema),
20782
+ z.record(z.string(), JsonValueSchema)
20783
+ ])
20784
+ );
20785
+ var SystemConfigSchema = z.record(z.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
20373
20786
  var SystemEntrySchema = z.object({
20374
- /** Stable tenant-defined system id (e.g. "sys.lead-gen"). */
20787
+ /** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
20375
20788
  id: SystemIdSchema,
20376
- /** Human-readable system title shown in governance and operations UI. */
20377
- title: LabelSchema,
20789
+ /** Human-readable system label shown in UI, governance, and operations surfaces. */
20790
+ label: LabelSchema.optional(),
20791
+ /** @deprecated Use label. Accepted for pre-consolidation System declarations. */
20792
+ title: LabelSchema.optional(),
20378
20793
  /** One-paragraph purpose statement for the bounded context. */
20379
- description: DescriptionSchema,
20794
+ description: DescriptionSchema.optional(),
20380
20795
  /** Closed system shape enum; catalog values remain tenant-defined. */
20381
- kind: SystemKindSchema,
20796
+ kind: SystemKindSchema.optional(),
20797
+ /** Optional self-reference for System hierarchy. */
20798
+ parentSystemId: SystemIdSchema.optional(),
20799
+ /** Optional UI presence. Systems without UI omit this. */
20800
+ ui: SystemUiSchema.optional(),
20801
+ /** Canonical lifecycle state. Replaces Feature.enabled/devOnly and System.status. */
20802
+ lifecycle: SystemLifecycleSchema.optional(),
20382
20803
  /** Optional role responsible for this system. */
20383
- responsibleRoleId: ModelIdSchema.optional(),
20804
+ responsibleRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
20384
20805
  /** Optional knowledge nodes that govern this system. */
20385
- governedByKnowledge: ReferenceIdsSchema,
20806
+ governedByKnowledge: z.array(ModelIdSchema.meta({ ref: "knowledge" })).default([]).optional(),
20807
+ /** Optional actions this system exposes or consumes. */
20808
+ actions: z.array(ActionRefSchema).optional(),
20809
+ /** Optional operational policies that apply to this system. */
20810
+ policies: z.array(ModelIdSchema.meta({ ref: "policy" })).default([]).optional(),
20386
20811
  /** Optional goals this system contributes to. */
20387
- drivesGoals: ReferenceIdsSchema,
20388
- status: SystemStatusSchema
20389
- });
20390
- var SystemsDomainSchema = z.object({
20391
- systems: z.array(SystemEntrySchema).default([])
20812
+ drivesGoals: z.array(ModelIdSchema.meta({ ref: "goal" })).default([]).optional(),
20813
+ /** @deprecated Use lifecycle. Accepted for one publish cycle. */
20814
+ status: SystemStatusSchema.optional(),
20815
+ /** @deprecated Use ui.path. Kept for one-cycle Feature compatibility. */
20816
+ path: PathSchema.optional(),
20817
+ /** @deprecated Use ui.icon. Kept for one-cycle Feature compatibility. */
20818
+ icon: IconNameSchema.optional(),
20819
+ /** @deprecated Feature color token, retained for one-cycle compatibility. */
20820
+ color: ColorTokenSchema.optional(),
20821
+ /** @deprecated UI placement hint, retained for one-cycle compatibility. */
20822
+ uiPosition: UiPositionSchema.optional(),
20823
+ /** @deprecated Use lifecycle. */
20824
+ enabled: z.boolean().optional(),
20825
+ /** @deprecated Use lifecycle: "beta". */
20826
+ devOnly: z.boolean().optional(),
20827
+ requiresAdmin: z.boolean().optional(),
20828
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20829
+ order: z.number(),
20830
+ /**
20831
+ * System-local JSON settings and defaults. Strongly typed OM fields,
20832
+ * secrets, credentials, and runtime state stay outside this bucket.
20833
+ */
20834
+ config: SystemConfigSchema,
20835
+ /**
20836
+ * System-owned ontology declarations. `systems` is now the canonical child
20837
+ * key; this scope holds the object, action, catalog, link, event, and
20838
+ * shared contract records owned by this system.
20839
+ */
20840
+ ontology: OntologyScopeSchema.optional(),
20841
+ /**
20842
+ * @deprecated Compatibility-only bridge for old tenant content nodes and
20843
+ * migration readers. New schema/catalog authoring belongs in ontology;
20844
+ * new system-local settings belong in config. Bridge nodes are keyed by
20845
+ * local NodeId and may still project to content-node:* graph IDs.
20846
+ */
20847
+ content: z.record(z.string().trim().min(1).max(200), ContentNodeSchema).optional(),
20848
+ /**
20849
+ * Recursive child systems, authored via nesting (per L11).
20850
+ * The key is the local system id; the full path is computed by joining
20851
+ * ancestor keys with `.` (e.g. parent key `'sales'` + child key `'crm'` → `'sales.crm'`).
20852
+ * Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
20853
+ * position-derived paths. Both still exist on this schema for backward compat.
20854
+ */
20855
+ systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
20856
+ /** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
20857
+ subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
20858
+ }).refine((system) => system.label !== void 0 || system.title !== void 0, {
20859
+ path: ["label"],
20860
+ message: "System must provide label or title"
20861
+ }).transform((system) => {
20862
+ const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
20863
+ if (normalizedSystem.status === void 0) return normalizedSystem;
20864
+ console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
20865
+ return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
20392
20866
  });
20393
- var DEFAULT_ORGANIZATION_MODEL_SYSTEMS = {
20394
- systems: []
20395
- };
20867
+ var SystemsDomainSchema = z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
20868
+ message: "Each system entry id must match its map key"
20869
+ }).default({});
20870
+ var DEFAULT_ORGANIZATION_MODEL_SYSTEMS = {};
20396
20871
 
20397
20872
  // src/organization-model/domains/resources.ts
20398
- z.enum(["workflow", "agent", "integration"]);
20399
- var ResourceGovernanceStatusSchema = z.enum(["active", "deprecated", "archived"]);
20400
- var AgentKindSchema = z.enum(["orchestrator", "specialist", "utility", "system"]);
20873
+ z.enum(["workflow", "agent", "integration", "script"]).meta({ label: "Resource kind", color: "orange" });
20874
+ var ResourceGovernanceStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Governance status", color: "teal" });
20875
+ var AgentKindSchema = z.enum(["orchestrator", "specialist", "utility", "platform"]).meta({ label: "Agent kind", color: "violet" });
20876
+ var ScriptResourceLanguageSchema = z.enum(["shell", "sql", "typescript", "python"]).meta({ label: "Language" });
20877
+ var CodeReferenceRoleSchema = z.enum(["entrypoint", "handler", "schema", "test", "docs", "config"]).meta({ label: "Code reference role", color: "blue" });
20401
20878
  var ResourceIdSchema = z.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
20879
+ var EventIdSchema = z.string().trim().min(1).max(300).regex(
20880
+ /^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*:[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
20881
+ "Event IDs must use <owner-id>:<event-key>"
20882
+ );
20883
+ var EventKeySchema = ModelIdSchema;
20884
+ var EventEmissionDescriptorSchema = z.object({
20885
+ eventKey: EventKeySchema,
20886
+ label: z.string().trim().min(1).max(120),
20887
+ payloadSchema: ModelIdSchema.optional(),
20888
+ lifecycle: SystemLifecycleSchema.optional()
20889
+ });
20890
+ EventEmissionDescriptorSchema.extend({
20891
+ id: EventIdSchema,
20892
+ ownerId: z.union([ResourceIdSchema, ModelIdSchema]),
20893
+ ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
20894
+ });
20895
+ var ResourceOntologyBindingSchema = z.object({
20896
+ implements: z.array(OntologyIdSchema).optional(),
20897
+ reads: z.array(OntologyIdSchema).optional(),
20898
+ writes: z.array(OntologyIdSchema).optional(),
20899
+ usesCatalogs: z.array(OntologyIdSchema).optional(),
20900
+ emits: z.array(OntologyIdSchema).optional()
20901
+ });
20902
+ var CodeReferenceSchema = z.object({
20903
+ path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
20904
+ role: CodeReferenceRoleSchema,
20905
+ symbol: z.string().trim().min(1).max(200).optional(),
20906
+ description: z.string().trim().min(1).max(300).optional()
20907
+ });
20402
20908
  var ResourceEntryBaseSchema = z.object({
20403
20909
  /** Canonical resource id; runtime resourceId derives from this value. */
20404
20910
  id: ResourceIdSchema,
20405
- /** Required single System membership. */
20406
- systemId: SystemIdSchema,
20911
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20912
+ order: z.number().default(0),
20913
+ /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
20914
+ systemPath: SystemPathSchema.meta({ ref: "system" }),
20407
20915
  /** Optional role responsible for maintaining this resource. */
20408
- ownerRoleId: ModelIdSchema.optional(),
20409
- status: ResourceGovernanceStatusSchema
20916
+ ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
20917
+ status: ResourceGovernanceStatusSchema,
20918
+ /**
20919
+ * Ontology contract bindings for the semantic work this resource performs.
20920
+ * `emits` stays nested here so top-level resource emits descriptors remain
20921
+ * compatible with graph event projection during the bridge.
20922
+ */
20923
+ ontology: ResourceOntologyBindingSchema.optional(),
20924
+ /** Repo-relative implementation breadcrumbs for agents and operators. */
20925
+ codeRefs: z.array(CodeReferenceSchema).default([])
20410
20926
  });
20411
20927
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
20412
20928
  kind: z.literal("workflow"),
20413
- /** Mirrors WorkflowConfig.capabilityKey when the runtime workflow has one. */
20414
- capabilityKey: z.string().trim().min(1).max(255).optional()
20929
+ /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
20930
+ actionKey: z.string().trim().min(1).max(255).optional(),
20931
+ emits: z.array(EventEmissionDescriptorSchema).optional()
20415
20932
  });
20416
20933
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
20417
20934
  kind: z.literal("agent"),
20418
20935
  /** Mirrors code-side AgentConfig.kind. */
20419
20936
  agentKind: AgentKindSchema,
20420
20937
  /** Role this agent embodies, if any. */
20421
- actsAsRoleId: ModelIdSchema.optional(),
20938
+ actsAsRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
20422
20939
  /** Mirrors AgentConfig.sessionCapable. */
20423
- sessionCapable: z.boolean()
20940
+ sessionCapable: z.boolean(),
20941
+ /** Broad/composite callable entry points orchestrated by this agent. */
20942
+ invocations: z.array(ActionInvocationSchema).default([]),
20943
+ emits: z.array(EventEmissionDescriptorSchema).optional()
20424
20944
  });
20425
20945
  var IntegrationResourceEntrySchema = ResourceEntryBaseSchema.extend({
20426
20946
  kind: z.literal("integration"),
20427
20947
  provider: z.string().trim().min(1).max(100)
20428
20948
  });
20949
+ var ScriptResourceSourceSchema = z.union([
20950
+ z.string().trim().min(1).max(5e4),
20951
+ z.object({
20952
+ file: z.string().trim().min(1).max(500)
20953
+ })
20954
+ ]);
20955
+ var ScriptResourceEntrySchema = ResourceEntryBaseSchema.extend({
20956
+ kind: z.literal("script"),
20957
+ language: ScriptResourceLanguageSchema,
20958
+ source: ScriptResourceSourceSchema
20959
+ });
20429
20960
  var ResourceEntrySchema = z.discriminatedUnion("kind", [
20430
20961
  WorkflowResourceEntrySchema,
20431
20962
  AgentResourceEntrySchema,
20432
- IntegrationResourceEntrySchema
20963
+ IntegrationResourceEntrySchema,
20964
+ ScriptResourceEntrySchema
20433
20965
  ]);
20434
- var ResourcesDomainSchema = z.object({
20435
- entries: z.array(ResourceEntrySchema).default([])
20436
- });
20437
- var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {
20438
- entries: []
20439
- };
20966
+ var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
20967
+ message: "Each resource entry id must match its map key"
20968
+ }).default({});
20969
+ var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
20440
20970
 
20441
20971
  // src/organization-model/domains/roles.ts
20442
20972
  var RoleIdSchema = ModelIdSchema;
@@ -20446,7 +20976,7 @@ var HumanRoleHolderSchema = z.object({
20446
20976
  });
20447
20977
  var AgentRoleHolderSchema = z.object({
20448
20978
  kind: z.literal("agent"),
20449
- agentId: ResourceIdSchema
20979
+ agentId: ResourceIdSchema.meta({ ref: "resource" })
20450
20980
  });
20451
20981
  var TeamRoleHolderSchema = z.object({
20452
20982
  kind: z.literal("team"),
@@ -20461,6 +20991,8 @@ var RoleHoldersSchema = z.union([RoleHolderSchema, z.array(RoleHolderSchema).min
20461
20991
  var RoleSchema = z.object({
20462
20992
  /** Stable unique identifier for the role (e.g. "role-ceo", "role-head-of-sales"). */
20463
20993
  id: RoleIdSchema,
20994
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
20995
+ order: z.number(),
20464
20996
  /** Human-readable title shown to agents and in UI (e.g. "CEO", "Head of Sales"). */
20465
20997
  title: z.string().trim().min(1).max(200),
20466
20998
  /**
@@ -20473,7 +21005,7 @@ var RoleSchema = z.object({
20473
21005
  * Optional: ID of another role this role reports to.
20474
21006
  * When present, must reference another `roles[].id` in the same organization.
20475
21007
  */
20476
- reportsToId: RoleIdSchema.optional(),
21008
+ reportsToId: RoleIdSchema.meta({ ref: "role" }).optional(),
20477
21009
  /**
20478
21010
  * Optional: human, agent, or team holder currently filling this role.
20479
21011
  * Agent holders reference OM Resource IDs and are validated at the model level.
@@ -20483,14 +21015,12 @@ var RoleSchema = z.object({
20483
21015
  * Optional Systems this role is accountable for.
20484
21016
  * Cross-reference enforced in `OrganizationModelSchema.superRefine()`.
20485
21017
  */
20486
- responsibleFor: z.array(SystemIdSchema).optional()
20487
- });
20488
- var RolesDomainSchema = z.object({
20489
- roles: z.array(RoleSchema).default([])
21018
+ responsibleFor: z.array(SystemIdSchema.meta({ ref: "system" })).optional()
20490
21019
  });
20491
- var DEFAULT_ORGANIZATION_MODEL_ROLES = {
20492
- roles: []
20493
- };
21020
+ var RolesDomainSchema = z.record(z.string(), RoleSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
21021
+ message: "Each role entry id must match its map key"
21022
+ }).default({});
21023
+ var DEFAULT_ORGANIZATION_MODEL_ROLES = {};
20494
21024
  var KeyResultSchema = z.object({
20495
21025
  /** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
20496
21026
  id: z.string().trim().min(1).max(100),
@@ -20514,6 +21044,8 @@ var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/;
20514
21044
  var ObjectiveSchema = z.object({
20515
21045
  /** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
20516
21046
  id: z.string().trim().min(1).max(100),
21047
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
21048
+ order: z.number(),
20517
21049
  /** Plain-language description of what the organization wants to achieve. */
20518
21050
  description: z.string().trim().min(1).max(1e3),
20519
21051
  /**
@@ -20533,180 +21065,75 @@ var ObjectiveSchema = z.object({
20533
21065
  */
20534
21066
  keyResults: z.array(KeyResultSchema).default([])
20535
21067
  });
20536
- var GoalsDomainSchema = z.object({
20537
- objectives: z.array(ObjectiveSchema).default([])
20538
- });
20539
- var DEFAULT_ORGANIZATION_MODEL_GOALS = {
20540
- objectives: []
20541
- };
20542
- var OperationSemanticClassSchema = z.enum(["queue", "executions", "sessions", "notifications", "schedules"]);
20543
- var OperationEntrySchema = z.object({
20544
- id: z.string().trim().min(1).max(100),
20545
- label: z.string().trim().min(1).max(120),
20546
- semanticClass: OperationSemanticClassSchema,
20547
- /** Optional reference to the feature that owns this runtime entity. */
20548
- featureId: z.string().trim().min(1).max(100).optional(),
20549
- /**
20550
- * Optional pointer to the status semanticClass values that apply to this
20551
- * entity ties operations back to the statuses domain for vibe rendering.
20552
- */
20553
- supportedStatusSemanticClass: z.array(z.string().trim().min(1).max(80)).optional()
20554
- });
20555
- var OperationsDomainSchema = z.object({
20556
- entries: z.array(OperationEntrySchema).default([])
21068
+ var GoalsDomainSchema = z.record(z.string(), ObjectiveSchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
21069
+ message: "Each objective entry id must match its map key"
21070
+ }).default({});
21071
+ var DEFAULT_ORGANIZATION_MODEL_GOALS = {};
21072
+ var KnowledgeTargetKindSchema = z.enum([
21073
+ "system",
21074
+ "resource",
21075
+ "knowledge",
21076
+ "stage",
21077
+ "action",
21078
+ "role",
21079
+ "goal",
21080
+ "customer-segment",
21081
+ "offering",
21082
+ "ontology",
21083
+ // D4: content nodes are a valid knowledge target after compound-domain data moved into system.content
21084
+ "content-node"
21085
+ ]).meta({ label: "Target kind" });
21086
+ var KnowledgeTargetRefSchema = z.object({
21087
+ kind: KnowledgeTargetKindSchema,
21088
+ // D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'.
21089
+ // Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
21090
+ // Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
21091
+ id: z.string().trim().min(1).max(300)
21092
+ }).superRefine((target, ctx) => {
21093
+ if (target.kind !== "ontology") return;
21094
+ const result = OntologyIdSchema.safeParse(target.id);
21095
+ if (!result.success) {
21096
+ ctx.addIssue({
21097
+ code: z.ZodIssueCode.custom,
21098
+ path: ["id"],
21099
+ message: "Ontology knowledge targets must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
21100
+ });
21101
+ }
20557
21102
  });
20558
- var DEFAULT_ORGANIZATION_MODEL_OPERATIONS = {
20559
- entries: [
20560
- // --- queue (HITL command queue) ---
20561
- {
20562
- id: "operations.queue",
20563
- label: "HITL Queue",
20564
- semanticClass: "queue",
20565
- featureId: "operations",
20566
- supportedStatusSemanticClass: ["queue"]
20567
- },
20568
- // --- executions (workflow / agent executions) ---
20569
- {
20570
- id: "operations.executions",
20571
- label: "Executions",
20572
- semanticClass: "executions",
20573
- featureId: "operations",
20574
- supportedStatusSemanticClass: ["execution"]
20575
- },
20576
- // --- sessions (agent conversation sessions) ---
20577
- {
20578
- id: "operations.sessions",
20579
- label: "Sessions",
20580
- semanticClass: "sessions",
20581
- featureId: "operations"
20582
- },
20583
- // --- notifications (platform in-app notifications) ---
20584
- {
20585
- id: "operations.notifications",
20586
- label: "Notifications",
20587
- semanticClass: "notifications",
20588
- featureId: "monitoring"
20589
- },
20590
- // --- schedules (task scheduler) ---
20591
- {
20592
- id: "operations.schedules",
20593
- label: "Schedules",
20594
- semanticClass: "schedules",
20595
- featureId: "operations",
20596
- supportedStatusSemanticClass: ["schedule", "schedule.run"]
20597
- }
20598
- ]
20599
- };
20600
- var StatusSemanticClassSchema = z.enum([
20601
- "delivery.task",
20602
- "delivery.project",
20603
- "delivery.milestone",
20604
- "queue",
20605
- "execution",
20606
- "schedule",
20607
- "schedule.run",
20608
- "request"
20609
- ]);
20610
- var StatusEntrySchema = z.object({
20611
- id: z.string().trim().min(1).max(100),
20612
- label: z.string().trim().min(1).max(120),
20613
- semanticClass: StatusSemanticClassSchema,
20614
- category: z.string().trim().min(1).max(80).optional()
21103
+ var LegacyKnowledgeLinkSchema = z.object({
21104
+ nodeId: z.union([NodeIdStringSchema, z.templateLiteral(["ontology:", OntologyIdSchema])])
20615
21105
  });
20616
- var StatusesDomainSchema = z.object({
20617
- entries: z.array(StatusEntrySchema).default([])
21106
+ var CanonicalKnowledgeLinkSchema = z.object({
21107
+ target: KnowledgeTargetRefSchema
20618
21108
  });
20619
- var DEFAULT_ORGANIZATION_MODEL_STATUSES = {
20620
- entries: [
20621
- // --- delivery.task (TaskStatus — 9 values) ---
20622
- { id: "delivery.task.planned", label: "Planned", semanticClass: "delivery.task", category: "delivery" },
20623
- { id: "delivery.task.in_progress", label: "In Progress", semanticClass: "delivery.task", category: "delivery" },
20624
- { id: "delivery.task.blocked", label: "Blocked", semanticClass: "delivery.task", category: "delivery" },
20625
- { id: "delivery.task.submitted", label: "Submitted", semanticClass: "delivery.task", category: "delivery" },
20626
- { id: "delivery.task.approved", label: "Approved", semanticClass: "delivery.task", category: "delivery" },
20627
- {
20628
- id: "delivery.task.revision_requested",
20629
- label: "Revision Requested",
20630
- semanticClass: "delivery.task",
20631
- category: "delivery"
20632
- },
20633
- { id: "delivery.task.rejected", label: "Rejected", semanticClass: "delivery.task", category: "delivery" },
20634
- { id: "delivery.task.cancelled", label: "Cancelled", semanticClass: "delivery.task", category: "delivery" },
20635
- { id: "delivery.task.completed", label: "Completed", semanticClass: "delivery.task", category: "delivery" },
20636
- // --- delivery.project (ProjectStatus — 6 values) ---
20637
- { id: "delivery.project.active", label: "Active", semanticClass: "delivery.project", category: "delivery" },
20638
- { id: "delivery.project.on_track", label: "On Track", semanticClass: "delivery.project", category: "delivery" },
20639
- { id: "delivery.project.at_risk", label: "At Risk", semanticClass: "delivery.project", category: "delivery" },
20640
- { id: "delivery.project.blocked", label: "Blocked", semanticClass: "delivery.project", category: "delivery" },
20641
- { id: "delivery.project.paused", label: "Paused", semanticClass: "delivery.project", category: "delivery" },
20642
- { id: "delivery.project.completed", label: "Completed", semanticClass: "delivery.project", category: "delivery" },
20643
- // --- delivery.milestone (MilestoneStatus — 5 values) ---
20644
- {
20645
- id: "delivery.milestone.upcoming",
20646
- label: "Upcoming",
20647
- semanticClass: "delivery.milestone",
20648
- category: "delivery"
20649
- },
20650
- {
20651
- id: "delivery.milestone.in_progress",
20652
- label: "In Progress",
20653
- semanticClass: "delivery.milestone",
20654
- category: "delivery"
20655
- },
20656
- {
20657
- id: "delivery.milestone.blocked",
20658
- label: "Blocked",
20659
- semanticClass: "delivery.milestone",
20660
- category: "delivery"
20661
- },
20662
- { id: "delivery.milestone.overdue", label: "Overdue", semanticClass: "delivery.milestone", category: "delivery" },
20663
- {
20664
- id: "delivery.milestone.completed",
20665
- label: "Completed",
20666
- semanticClass: "delivery.milestone",
20667
- category: "delivery"
20668
- },
20669
- // --- queue (QueueTaskStatus — 5 values, maps hitl/command-queue tasks) ---
20670
- { id: "queue.pending", label: "Pending", semanticClass: "queue", category: "queue" },
20671
- { id: "queue.processing", label: "Processing", semanticClass: "queue", category: "queue" },
20672
- { id: "queue.completed", label: "Completed", semanticClass: "queue", category: "queue" },
20673
- { id: "queue.failed", label: "Failed", semanticClass: "queue", category: "queue" },
20674
- { id: "queue.expired", label: "Expired", semanticClass: "queue", category: "queue" },
20675
- // --- execution (ExecutionStatus — 5 values) ---
20676
- { id: "execution.pending", label: "Pending", semanticClass: "execution", category: "execution" },
20677
- { id: "execution.running", label: "Running", semanticClass: "execution", category: "execution" },
20678
- { id: "execution.completed", label: "Completed", semanticClass: "execution", category: "execution" },
20679
- { id: "execution.failed", label: "Failed", semanticClass: "execution", category: "execution" },
20680
- { id: "execution.warning", label: "Warning", semanticClass: "execution", category: "execution" },
20681
- // --- schedule (schedule status — 4 values) ---
20682
- { id: "schedule.active", label: "Active", semanticClass: "schedule", category: "schedule" },
20683
- { id: "schedule.paused", label: "Paused", semanticClass: "schedule", category: "schedule" },
20684
- { id: "schedule.completed", label: "Completed", semanticClass: "schedule", category: "schedule" },
20685
- { id: "schedule.cancelled", label: "Cancelled", semanticClass: "schedule", category: "schedule" },
20686
- // --- schedule.run (schedule run status — 4 values) ---
20687
- { id: "schedule.run.running", label: "Running", semanticClass: "schedule.run", category: "schedule" },
20688
- { id: "schedule.run.completed", label: "Completed", semanticClass: "schedule.run", category: "schedule" },
20689
- { id: "schedule.run.failed", label: "Failed", semanticClass: "schedule.run", category: "schedule" },
20690
- { id: "schedule.run.cancelled", label: "Cancelled", semanticClass: "schedule.run", category: "schedule" },
20691
- // --- request (RequestStatus — 4 values, maps reported_requests) ---
20692
- { id: "request.open", label: "Open", semanticClass: "request", category: "request" },
20693
- { id: "request.investigating", label: "Investigating", semanticClass: "request", category: "request" },
20694
- { id: "request.resolved", label: "Resolved", semanticClass: "request", category: "request" },
20695
- { id: "request.wont_fix", label: "Won't Fix", semanticClass: "request", category: "request" }
20696
- ]
20697
- };
20698
- var KnowledgeLinkSchema = z.object({
20699
- nodeId: NodeIdStringSchema
21109
+ function nodeIdFromTarget(target) {
21110
+ return `${target.kind}:${target.id}`;
21111
+ }
21112
+ function targetFromNodeId(nodeId) {
21113
+ const [kind, ...idParts] = nodeId.split(":");
21114
+ return {
21115
+ kind: KnowledgeTargetKindSchema.parse(kind),
21116
+ id: idParts.join(":")
21117
+ };
21118
+ }
21119
+ var KnowledgeLinkSchema = z.union([CanonicalKnowledgeLinkSchema, LegacyKnowledgeLinkSchema]).transform((link) => {
21120
+ const target = "target" in link ? link.target : targetFromNodeId(link.nodeId);
21121
+ return {
21122
+ target,
21123
+ nodeId: nodeIdFromTarget(target)
21124
+ };
20700
21125
  });
20701
- var KnowledgeSkillBindingSchema = z.string().trim().min(1).max(120);
20702
- var KnowledgeDomainBindingSchema = z.string().trim().min(1).max(80);
20703
- var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]);
21126
+ var OrgKnowledgeKindSchema = z.enum(["playbook", "strategy", "reference"]).meta({ label: "Knowledge kind", color: "grape" });
20704
21127
  var OrgKnowledgeNodeSchema = z.object({
20705
21128
  id: ModelIdSchema,
20706
21129
  kind: OrgKnowledgeKindSchema,
20707
21130
  title: z.string().trim().min(1).max(200),
20708
21131
  summary: z.string().trim().min(1).max(1e3),
20709
21132
  icon: IconNameSchema.optional(),
21133
+ /** Canonical documentation URL when body content is a local summary. */
21134
+ externalUrl: z.string().trim().url().max(500).optional(),
21135
+ /** Optional generated source file path for local MDX-backed knowledge nodes. */
21136
+ sourceFilePath: z.string().trim().min(1).max(500).optional(),
20710
21137
  /** Raw MDX string. Phase 2 will introduce a structured block format. */
20711
21138
  body: z.string().trim().min(1),
20712
21139
  /**
@@ -20714,38 +21141,158 @@ var OrgKnowledgeNodeSchema = z.object({
20714
21141
  * Each link emits a `governs` edge: knowledge-node -> target node.
20715
21142
  */
20716
21143
  links: z.array(KnowledgeLinkSchema).default([]),
20717
- /** Operator skill or command bindings relevant to this node. */
20718
- skills: z.array(KnowledgeSkillBindingSchema).optional(),
20719
- /** Domain key used to derive fast graph->skill registries. */
20720
- domain: KnowledgeDomainBindingSchema.optional(),
20721
21144
  /** Role identifiers that own this knowledge node. */
20722
- ownerIds: z.array(RoleIdSchema).default([]),
21145
+ ownerIds: z.array(RoleIdSchema.meta({ ref: "role" })).default([]),
20723
21146
  /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
20724
21147
  updatedAt: z.string().trim().min(1).max(50)
20725
21148
  });
20726
- var KnowledgeDomainSchema = z.object({
20727
- nodes: z.array(OrgKnowledgeNodeSchema).default([])
21149
+ var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
21150
+ var PolicyIdSchema = ModelIdSchema;
21151
+ var PolicyApplicabilitySchema = z.object({
21152
+ systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
21153
+ actionIds: z.array(ModelIdSchema.meta({ ref: "action" })).default([]),
21154
+ resourceIds: z.array(ModelIdSchema.meta({ ref: "resource" })).default([]),
21155
+ roleIds: z.array(ModelIdSchema.meta({ ref: "role" })).default([])
20728
21156
  });
21157
+ var PolicyTriggerSchema = z.discriminatedUnion("kind", [
21158
+ z.object({
21159
+ kind: z.literal("event"),
21160
+ eventId: EventIdSchema.meta({ ref: "event" })
21161
+ }),
21162
+ z.object({
21163
+ kind: z.literal("action-invocation"),
21164
+ actionId: ModelIdSchema.meta({ ref: "action" })
21165
+ }),
21166
+ z.object({
21167
+ kind: z.literal("schedule"),
21168
+ cron: z.string().trim().min(1).max(120)
21169
+ }),
21170
+ z.object({
21171
+ kind: z.literal("manual")
21172
+ })
21173
+ ]);
21174
+ var PolicyPredicateSchema = z.discriminatedUnion("kind", [
21175
+ z.object({
21176
+ kind: z.literal("always")
21177
+ }),
21178
+ z.object({
21179
+ kind: z.literal("expression"),
21180
+ expression: z.string().trim().min(1).max(2e3)
21181
+ }),
21182
+ z.object({
21183
+ kind: z.literal("threshold"),
21184
+ metric: ModelIdSchema,
21185
+ operator: z.enum(["lt", "lte", "eq", "gte", "gt"]).meta({ label: "Operator" }),
21186
+ value: z.number()
21187
+ })
21188
+ ]);
21189
+ var PolicyEffectSchema = z.discriminatedUnion("kind", [
21190
+ z.object({
21191
+ kind: z.literal("require-approval"),
21192
+ roleId: ModelIdSchema.meta({ ref: "role" }).optional()
21193
+ }),
21194
+ z.object({
21195
+ kind: z.literal("invoke-action"),
21196
+ actionId: ModelIdSchema.meta({ ref: "action" })
21197
+ }),
21198
+ z.object({
21199
+ kind: z.literal("notify-role"),
21200
+ roleId: ModelIdSchema.meta({ ref: "role" })
21201
+ }),
21202
+ z.object({
21203
+ kind: z.literal("block")
21204
+ })
21205
+ ]);
21206
+ var PolicySchema = z.object({
21207
+ id: PolicyIdSchema,
21208
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
21209
+ order: z.number(),
21210
+ label: LabelSchema,
21211
+ description: DescriptionSchema.optional(),
21212
+ trigger: PolicyTriggerSchema,
21213
+ predicate: PolicyPredicateSchema.default({ kind: "always" }),
21214
+ actions: z.array(PolicyEffectSchema).min(1),
21215
+ appliesTo: PolicyApplicabilitySchema.default({
21216
+ systemIds: [],
21217
+ actionIds: [],
21218
+ resourceIds: [],
21219
+ roleIds: []
21220
+ }),
21221
+ lifecycle: z.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" }).default("active")
21222
+ });
21223
+ var PoliciesDomainSchema = z.record(z.string(), PolicySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
21224
+ message: "Each policy entry id must match its map key"
21225
+ }).default({});
21226
+ var DEFAULT_ORGANIZATION_MODEL_POLICIES = {};
20729
21227
 
20730
21228
  // src/organization-model/schema.ts
21229
+ z.enum([
21230
+ "branding",
21231
+ "identity",
21232
+ "customers",
21233
+ "offerings",
21234
+ "roles",
21235
+ "goals",
21236
+ "systems",
21237
+ "ontology",
21238
+ "resources",
21239
+ "actions",
21240
+ "entities",
21241
+ "policies",
21242
+ "knowledge"
21243
+ ]);
21244
+ var OrganizationModelDomainMetadataSchema = z.object({
21245
+ version: z.literal(1).default(1),
21246
+ lastModified: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, "lastModified must be an ISO date string (YYYY-MM-DD)")
21247
+ });
21248
+ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
21249
+ branding: { version: 1, lastModified: "2026-05-10" },
21250
+ identity: { version: 1, lastModified: "2026-05-10" },
21251
+ customers: { version: 1, lastModified: "2026-05-10" },
21252
+ offerings: { version: 1, lastModified: "2026-05-10" },
21253
+ roles: { version: 1, lastModified: "2026-05-10" },
21254
+ goals: { version: 1, lastModified: "2026-05-10" },
21255
+ systems: { version: 1, lastModified: "2026-05-10" },
21256
+ ontology: { version: 1, lastModified: "2026-05-14" },
21257
+ resources: { version: 1, lastModified: "2026-05-10" },
21258
+ actions: { version: 1, lastModified: "2026-05-10" },
21259
+ entities: { version: 1, lastModified: "2026-05-10" },
21260
+ policies: { version: 1, lastModified: "2026-05-10" },
21261
+ knowledge: { version: 1, lastModified: "2026-05-10" }
21262
+ };
21263
+ var OrganizationModelDomainMetadataByDomainSchema = z.object({
21264
+ branding: OrganizationModelDomainMetadataSchema,
21265
+ identity: OrganizationModelDomainMetadataSchema,
21266
+ customers: OrganizationModelDomainMetadataSchema,
21267
+ offerings: OrganizationModelDomainMetadataSchema,
21268
+ roles: OrganizationModelDomainMetadataSchema,
21269
+ goals: OrganizationModelDomainMetadataSchema,
21270
+ systems: OrganizationModelDomainMetadataSchema,
21271
+ ontology: OrganizationModelDomainMetadataSchema,
21272
+ resources: OrganizationModelDomainMetadataSchema,
21273
+ actions: OrganizationModelDomainMetadataSchema,
21274
+ entities: OrganizationModelDomainMetadataSchema,
21275
+ policies: OrganizationModelDomainMetadataSchema,
21276
+ knowledge: OrganizationModelDomainMetadataSchema
21277
+ }).partial().default(DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA).transform((metadata) => ({ ...DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA, ...metadata }));
20731
21278
  var OrganizationModelSchemaBase = z.object({
20732
21279
  version: z.literal(1).default(1),
20733
- features: z.array(FeatureSchema).default([]),
21280
+ domainMetadata: OrganizationModelDomainMetadataByDomainSchema,
20734
21281
  branding: OrganizationModelBrandingSchema,
20735
- navigation: OrganizationModelNavigationSchema.default({ surfaces: [], groups: [] }),
20736
- sales: OrganizationModelSalesSchema,
20737
- prospecting: OrganizationModelProspectingSchema,
20738
- projects: OrganizationModelProjectsSchema,
21282
+ navigation: OrganizationModelNavigationSchema,
20739
21283
  identity: IdentityDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_IDENTITY),
20740
21284
  customers: CustomersDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_CUSTOMERS),
20741
21285
  offerings: OfferingsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_OFFERINGS),
20742
21286
  roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
20743
21287
  goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
20744
21288
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
21289
+ ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
20745
21290
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
20746
- statuses: StatusesDomainSchema.default({ entries: [] }),
20747
- operations: OperationsDomainSchema.default({ entries: [] }),
20748
- knowledge: KnowledgeDomainSchema.default({ nodes: [] })
21291
+ actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
21292
+ entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
21293
+ policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
21294
+ // D3: flat Record<id, OrgKnowledgeNode> — no wrapper object
21295
+ knowledge: KnowledgeDomainSchema.default({})
20749
21296
  });
20750
21297
  function addIssue(ctx, path, message) {
20751
21298
  ctx.addIssue({
@@ -20754,217 +21301,493 @@ function addIssue(ctx, path, message) {
20754
21301
  message
20755
21302
  });
20756
21303
  }
20757
- function collectIds(items, ctx, collectionPath, label) {
20758
- const itemsById = /* @__PURE__ */ new Map();
20759
- items.forEach((item, index2) => {
20760
- if (itemsById.has(item.id)) {
20761
- addIssue(ctx, [...collectionPath, index2, "id"], `${label} id "${item.id}" must be unique`);
20762
- return;
20763
- }
20764
- itemsById.set(item.id, item);
20765
- });
20766
- return itemsById;
20767
- }
20768
- var LEGACY_FEATURE_ALIASES = /* @__PURE__ */ new Map([
20769
- ["crm", "sales.crm"],
20770
- ["lead-gen", "sales.lead-gen"],
20771
- ["submitted-requests", "monitoring.submitted-requests"]
20772
- ]);
20773
- function hasFeature(featuresById, featureId) {
20774
- return featuresById.has(featureId) || featuresById.has(LEGACY_FEATURE_ALIASES.get(featureId) ?? "");
21304
+ function isLifecycleEnabled(lifecycle, enabled) {
21305
+ if (enabled === false) return false;
21306
+ return lifecycle !== "deprecated" && lifecycle !== "archived";
20775
21307
  }
20776
- function defaultFeaturePathFor(id) {
21308
+ function defaultSystemPathFor(id) {
20777
21309
  return `/${id.replaceAll(".", "/")}`;
20778
21310
  }
20779
21311
  function asRoleHolderArray(heldBy) {
20780
21312
  return Array.isArray(heldBy) ? heldBy : [heldBy];
20781
21313
  }
21314
+ function isKnowledgeKindCompatibleWithTarget(knowledgeKind, targetKind) {
21315
+ if (knowledgeKind === "reference") return true;
21316
+ if (knowledgeKind === "playbook") {
21317
+ return ["system", "resource", "stage", "action", "ontology"].includes(targetKind);
21318
+ }
21319
+ if (knowledgeKind === "strategy") {
21320
+ return ["system", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
21321
+ }
21322
+ return false;
21323
+ }
21324
+ function isRecord(value) {
21325
+ return typeof value === "object" && value !== null && !Array.isArray(value);
21326
+ }
20782
21327
  var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
20783
- const featuresById = collectIds(model.features, ctx, ["features"], "Feature");
20784
- const featureIdsByEffectivePath = /* @__PURE__ */ new Map();
20785
- model.features.forEach((feature, featureIndex) => {
20786
- const segments = feature.id.split(".");
20787
- if (segments.length > 1) {
20788
- const parentId = segments.slice(0, -1).join(".");
20789
- if (!featuresById.has(parentId)) {
20790
- addIssue(
20791
- ctx,
20792
- ["features", featureIndex, "id"],
20793
- `Feature "${feature.id}" references unknown parent "${parentId}"`
21328
+ function collectAllSystems(systems, prefix = "", schemaPath = ["systems"]) {
21329
+ const result = [];
21330
+ for (const [key, system] of Object.entries(systems)) {
21331
+ const path = prefix ? `${prefix}.${key}` : key;
21332
+ const currentSchemaPath = [...schemaPath, key];
21333
+ result.push({ path, schemaPath: currentSchemaPath, system });
21334
+ const childSystems = system.systems ?? system.subsystems;
21335
+ if (childSystems !== void 0) {
21336
+ result.push(
21337
+ ...collectAllSystems(childSystems, path, [...currentSchemaPath, system.systems !== void 0 ? "systems" : "subsystems"])
20794
21338
  );
20795
21339
  }
20796
21340
  }
20797
- const hasChildren = model.features.some(
20798
- (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.id !== feature.id
20799
- );
20800
- const contributesRoutePath = feature.path !== void 0 || !hasChildren;
21341
+ return result;
21342
+ }
21343
+ const allSystems = collectAllSystems(model.systems);
21344
+ const systemsById = /* @__PURE__ */ new Map();
21345
+ for (const { path, system } of allSystems) {
21346
+ systemsById.set(path, system);
21347
+ systemsById.set(system.id, system);
21348
+ }
21349
+ const systemIdsByEffectivePath = /* @__PURE__ */ new Map();
21350
+ allSystems.forEach(({ path, schemaPath, system }) => {
21351
+ if (system.parentSystemId !== void 0 && !systemsById.has(system.parentSystemId)) {
21352
+ addIssue(
21353
+ ctx,
21354
+ [...schemaPath, "parentSystemId"],
21355
+ `System "${system.id}" references unknown parent "${system.parentSystemId}"`
21356
+ );
21357
+ }
21358
+ const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes("."));
21359
+ const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
20801
21360
  if (contributesRoutePath) {
20802
- const effectivePath = feature.path ?? defaultFeaturePathFor(feature.id);
20803
- const existingFeatureId = featureIdsByEffectivePath.get(effectivePath);
20804
- if (existingFeatureId !== void 0) {
21361
+ const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path);
21362
+ const existingSystemId = systemIdsByEffectivePath.get(effectivePath);
21363
+ if (existingSystemId !== void 0) {
20805
21364
  addIssue(
20806
21365
  ctx,
20807
- ["features", featureIndex, feature.path === void 0 ? "id" : "path"],
20808
- `Feature "${feature.id}" effective path "${effectivePath}" duplicates feature "${existingFeatureId}"`
21366
+ [...schemaPath, system.ui?.path !== void 0 ? "ui" : "path"],
21367
+ `System "${path}" effective path "${effectivePath}" duplicates system "${existingSystemId}"`
20809
21368
  );
20810
21369
  } else {
20811
- featureIdsByEffectivePath.set(effectivePath, feature.id);
21370
+ systemIdsByEffectivePath.set(effectivePath, path);
20812
21371
  }
20813
21372
  }
20814
- if (hasChildren && feature.enabled) {
20815
- const hasEnabledDescendant = model.features.some(
20816
- (candidate) => candidate.id.startsWith(`${feature.id}.`) && candidate.enabled
21373
+ if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
21374
+ const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
21375
+ (candidate) => isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
21376
+ ) || allSystems.some(
21377
+ (candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
20817
21378
  );
20818
21379
  if (!hasEnabledDescendant) {
20819
21380
  addIssue(
20820
21381
  ctx,
20821
- ["features", featureIndex, "enabled"],
20822
- `Feature "${feature.id}" is enabled but has no enabled descendants`
21382
+ [...schemaPath, "lifecycle"],
21383
+ `System "${path}" is active but has no active descendants`
20823
21384
  );
20824
21385
  }
20825
21386
  }
20826
21387
  });
20827
- const surfacesById = collectIds(model.navigation.surfaces, ctx, ["navigation", "surfaces"], "Navigation surface");
20828
- if (model.navigation.defaultSurfaceId !== void 0 && !surfacesById.has(model.navigation.defaultSurfaceId)) {
20829
- addIssue(
20830
- ctx,
20831
- ["navigation", "defaultSurfaceId"],
20832
- `Navigation defaultSurfaceId references unknown surface "${model.navigation.defaultSurfaceId}"`
20833
- );
21388
+ allSystems.forEach(({ schemaPath, system }) => {
21389
+ const visited = /* @__PURE__ */ new Set();
21390
+ let currentParentId = system.parentSystemId;
21391
+ while (currentParentId !== void 0) {
21392
+ if (currentParentId === system.id || visited.has(currentParentId)) {
21393
+ addIssue(ctx, [...schemaPath, "parentSystemId"], `System "${system.id}" has a parent cycle`);
21394
+ return;
21395
+ }
21396
+ visited.add(currentParentId);
21397
+ currentParentId = systemsById.get(currentParentId)?.parentSystemId;
21398
+ }
21399
+ });
21400
+ function normalizeRoutePath(path) {
21401
+ return path.length > 1 ? path.replace(/\/+$/, "") : path;
21402
+ }
21403
+ const sidebarNodeIds = /* @__PURE__ */ new Map();
21404
+ const sidebarSurfacePaths = /* @__PURE__ */ new Map();
21405
+ const sidebarSurfaces = [];
21406
+ function collectSidebarNodes(nodes, schemaPath) {
21407
+ Object.entries(nodes).forEach(([nodeId, node]) => {
21408
+ const nodePath = [...schemaPath, nodeId];
21409
+ const existingNodePath = sidebarNodeIds.get(nodeId);
21410
+ if (existingNodePath !== void 0) {
21411
+ addIssue(ctx, nodePath, `Sidebar node id "${nodeId}" duplicates another sidebar node`);
21412
+ } else {
21413
+ sidebarNodeIds.set(nodeId, nodePath);
21414
+ }
21415
+ if (node.type === "group") {
21416
+ collectSidebarNodes(node.children, [...nodePath, "children"]);
21417
+ return;
21418
+ }
21419
+ sidebarSurfaces.push({ id: nodeId, node, path: nodePath });
21420
+ const normalizedPath = normalizeRoutePath(node.path);
21421
+ const existingSurfaceId = sidebarSurfacePaths.get(normalizedPath);
21422
+ if (existingSurfaceId !== void 0) {
21423
+ addIssue(
21424
+ ctx,
21425
+ [...nodePath, "path"],
21426
+ `Sidebar surface path "${node.path}" duplicates surface "${existingSurfaceId}"`
21427
+ );
21428
+ } else {
21429
+ sidebarSurfacePaths.set(normalizedPath, nodeId);
21430
+ }
21431
+ node.targets?.systems?.forEach((systemId, systemIndex) => {
21432
+ if (!systemsById.has(systemId)) {
21433
+ addIssue(
21434
+ ctx,
21435
+ [...nodePath, "targets", "systems", systemIndex],
21436
+ `Sidebar surface "${nodeId}" references unknown system "${systemId}"`
21437
+ );
21438
+ }
21439
+ });
21440
+ });
20834
21441
  }
20835
- model.navigation.groups.forEach((group, groupIndex) => {
20836
- group.surfaceIds.forEach((surfaceId, surfaceIndex) => {
20837
- if (!surfacesById.has(surfaceId)) {
21442
+ collectSidebarNodes(model.navigation.sidebar.primary, ["navigation", "sidebar", "primary"]);
21443
+ collectSidebarNodes(model.navigation.sidebar.bottom, ["navigation", "sidebar", "bottom"]);
21444
+ const segmentsById = new Map(Object.entries(model.customers));
21445
+ Object.values(model.offerings).forEach((product) => {
21446
+ product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
21447
+ if (!segmentsById.has(segmentId)) {
20838
21448
  addIssue(
20839
21449
  ctx,
20840
- ["navigation", "groups", groupIndex, "surfaceIds", surfaceIndex],
20841
- `Navigation group "${group.id}" references unknown surface "${surfaceId}"`
21450
+ ["offerings", product.id, "targetSegmentIds", segmentIndex],
21451
+ `Product "${product.id}" references unknown customer segment "${segmentId}"`
20842
21452
  );
20843
21453
  }
20844
21454
  });
21455
+ if (product.deliveryFeatureId !== void 0 && !systemsById.has(product.deliveryFeatureId)) {
21456
+ addIssue(
21457
+ ctx,
21458
+ ["offerings", product.id, "deliveryFeatureId"],
21459
+ `Product "${product.id}" references unknown delivery system "${product.deliveryFeatureId}"`
21460
+ );
21461
+ }
20845
21462
  });
20846
- model.navigation.surfaces.forEach((surface, surfaceIndex) => {
20847
- if (surface.featureId !== void 0 && !hasFeature(featuresById, surface.featureId)) {
21463
+ Object.values(model.goals).forEach((objective) => {
21464
+ if (objective.periodEnd <= objective.periodStart) {
20848
21465
  addIssue(
20849
21466
  ctx,
20850
- ["navigation", "surfaces", surfaceIndex, "featureId"],
20851
- `Navigation surface "${surface.id}" references unknown feature "${surface.featureId}"`
21467
+ ["goals", objective.id, "periodEnd"],
21468
+ `Goal "${objective.id}" has periodEnd "${objective.periodEnd}" which must be strictly after periodStart "${objective.periodStart}"`
20852
21469
  );
20853
21470
  }
20854
- surface.featureIds.forEach((featureId, featureIndex) => {
20855
- if (!hasFeature(featuresById, featureId)) {
21471
+ });
21472
+ const goalsById = new Map(Object.entries(model.goals));
21473
+ const knowledgeById = new Map(Object.entries(model.knowledge));
21474
+ const actionsById = new Map(Object.entries(model.actions));
21475
+ const entitiesById = new Map(Object.entries(model.entities));
21476
+ const policiesById = new Map(Object.entries(model.policies));
21477
+ sidebarSurfaces.forEach(({ id, node, path }) => {
21478
+ node.targets?.entities?.forEach((entityId, entityIndex) => {
21479
+ if (!entitiesById.has(entityId)) {
20856
21480
  addIssue(
20857
21481
  ctx,
20858
- ["navigation", "surfaces", surfaceIndex, "featureIds", featureIndex],
20859
- `Navigation surface "${surface.id}" references unknown feature "${featureId}"`
21482
+ [...path, "targets", "entities", entityIndex],
21483
+ `Sidebar surface "${id}" references unknown entity "${entityId}"`
20860
21484
  );
20861
21485
  }
20862
21486
  });
20863
- });
20864
- const segmentsById = new Map(model.customers.segments.map((seg) => [seg.id, seg]));
20865
- model.offerings.products.forEach((product, productIndex) => {
20866
- product.targetSegmentIds.forEach((segmentId, segmentIndex) => {
20867
- if (!segmentsById.has(segmentId)) {
21487
+ node.targets?.actions?.forEach((actionId, actionIndex) => {
21488
+ if (!actionsById.has(actionId)) {
20868
21489
  addIssue(
20869
21490
  ctx,
20870
- ["offerings", "products", productIndex, "targetSegmentIds", segmentIndex],
20871
- `Product "${product.id}" references unknown customer segment "${segmentId}"`
21491
+ [...path, "targets", "actions", actionIndex],
21492
+ `Sidebar surface "${id}" references unknown action "${actionId}"`
20872
21493
  );
20873
21494
  }
20874
21495
  });
20875
- if (product.deliveryFeatureId !== void 0 && !hasFeature(featuresById, product.deliveryFeatureId)) {
20876
- addIssue(
20877
- ctx,
20878
- ["offerings", "products", productIndex, "deliveryFeatureId"],
20879
- `Product "${product.id}" references unknown delivery feature "${product.deliveryFeatureId}"`
20880
- );
20881
- }
20882
21496
  });
20883
- model.goals.objectives.forEach((objective, index2) => {
20884
- if (objective.periodEnd <= objective.periodStart) {
21497
+ Object.values(model.entities).forEach((entity) => {
21498
+ if (!systemsById.has(entity.ownedBySystemId)) {
20885
21499
  addIssue(
20886
21500
  ctx,
20887
- ["goals", "objectives", index2, "periodEnd"],
20888
- `Goal "${objective.id}" has periodEnd "${objective.periodEnd}" which must be strictly after periodStart "${objective.periodStart}"`
21501
+ ["entities", entity.id, "ownedBySystemId"],
21502
+ `Entity "${entity.id}" references unknown ownedBySystemId "${entity.ownedBySystemId}"`
20889
21503
  );
20890
21504
  }
21505
+ entity.links?.forEach((link, linkIndex) => {
21506
+ if (!entitiesById.has(link.toEntity)) {
21507
+ addIssue(
21508
+ ctx,
21509
+ ["entities", entity.id, "links", linkIndex, "toEntity"],
21510
+ `Entity "${entity.id}" links to unknown entity "${link.toEntity}"`
21511
+ );
21512
+ }
21513
+ });
20891
21514
  });
20892
- const goalsById = new Map(model.goals.objectives.map((objective) => [objective.id, objective]));
20893
- const knowledgeById = new Map(model.knowledge.nodes.map((node) => [node.id, node]));
20894
- const rolesById = new Map(model.roles.roles.map((role) => [role.id, role]));
20895
- model.roles.roles.forEach((role, roleIndex) => {
21515
+ const rolesById = new Map(Object.entries(model.roles));
21516
+ Object.values(model.roles).forEach((role) => {
20896
21517
  if (role.reportsToId !== void 0 && !rolesById.has(role.reportsToId)) {
20897
21518
  addIssue(
20898
21519
  ctx,
20899
- ["roles", "roles", roleIndex, "reportsToId"],
21520
+ ["roles", role.id, "reportsToId"],
20900
21521
  `Role "${role.id}" references unknown reportsToId "${role.reportsToId}"`
20901
21522
  );
20902
21523
  }
20903
21524
  });
20904
- const systemsById = collectIds(model.systems.systems, ctx, ["systems", "systems"], "System");
20905
- model.roles.roles.forEach((role, roleIndex) => {
21525
+ Object.values(model.roles).forEach((role) => {
21526
+ const visited = /* @__PURE__ */ new Set();
21527
+ let currentReportsToId = role.reportsToId;
21528
+ while (currentReportsToId !== void 0) {
21529
+ if (currentReportsToId === role.id || visited.has(currentReportsToId)) {
21530
+ addIssue(ctx, ["roles", role.id, "reportsToId"], `Role "${role.id}" has a reportsToId cycle`);
21531
+ return;
21532
+ }
21533
+ visited.add(currentReportsToId);
21534
+ currentReportsToId = rolesById.get(currentReportsToId)?.reportsToId;
21535
+ }
21536
+ });
21537
+ Object.values(model.roles).forEach((role) => {
20906
21538
  role.responsibleFor?.forEach((systemId, systemIndex) => {
20907
21539
  if (!systemsById.has(systemId)) {
20908
21540
  addIssue(
20909
21541
  ctx,
20910
- ["roles", "roles", roleIndex, "responsibleFor", systemIndex],
21542
+ ["roles", role.id, "responsibleFor", systemIndex],
20911
21543
  `Role "${role.id}" references unknown responsibleFor system "${systemId}"`
20912
21544
  );
20913
21545
  }
20914
21546
  });
20915
21547
  });
20916
- model.systems.systems.forEach((system, systemIndex) => {
21548
+ allSystems.forEach(({ schemaPath, system }) => {
20917
21549
  if (system.responsibleRoleId !== void 0 && !rolesById.has(system.responsibleRoleId)) {
20918
21550
  addIssue(
20919
21551
  ctx,
20920
- ["systems", "systems", systemIndex, "responsibleRoleId"],
21552
+ [...schemaPath, "responsibleRoleId"],
20921
21553
  `System "${system.id}" references unknown responsibleRoleId "${system.responsibleRoleId}"`
20922
21554
  );
20923
21555
  }
20924
- system.governedByKnowledge.forEach((nodeId, nodeIndex) => {
21556
+ system.governedByKnowledge?.forEach((nodeId, nodeIndex) => {
20925
21557
  if (!knowledgeById.has(nodeId)) {
20926
21558
  addIssue(
20927
21559
  ctx,
20928
- ["systems", "systems", systemIndex, "governedByKnowledge", nodeIndex],
21560
+ [...schemaPath, "governedByKnowledge", nodeIndex],
20929
21561
  `System "${system.id}" references unknown knowledge node "${nodeId}"`
20930
21562
  );
20931
21563
  }
20932
21564
  });
20933
- system.drivesGoals.forEach((goalId, goalIndex) => {
21565
+ system.drivesGoals?.forEach((goalId, goalIndex) => {
20934
21566
  if (!goalsById.has(goalId)) {
20935
21567
  addIssue(
20936
21568
  ctx,
20937
- ["systems", "systems", systemIndex, "drivesGoals", goalIndex],
21569
+ [...schemaPath, "drivesGoals", goalIndex],
20938
21570
  `System "${system.id}" references unknown goal "${goalId}"`
20939
21571
  );
20940
21572
  }
20941
21573
  });
21574
+ system.actions?.forEach((actionRef, actionIndex) => {
21575
+ if (!actionsById.has(actionRef.actionId)) {
21576
+ addIssue(
21577
+ ctx,
21578
+ [...schemaPath, "actions", actionIndex, "actionId"],
21579
+ `System "${system.id}" references unknown action "${actionRef.actionId}"`
21580
+ );
21581
+ }
21582
+ });
21583
+ system.policies?.forEach((policyId, policyIndex) => {
21584
+ if (!policiesById.has(policyId)) {
21585
+ addIssue(
21586
+ ctx,
21587
+ [...schemaPath, "policies", policyIndex],
21588
+ `System "${system.id}" references unknown policy "${policyId}"`
21589
+ );
21590
+ }
21591
+ });
21592
+ });
21593
+ Object.values(model.actions).forEach((action) => {
21594
+ action.affects?.forEach((entityId, entityIndex) => {
21595
+ if (!entitiesById.has(entityId)) {
21596
+ addIssue(
21597
+ ctx,
21598
+ ["actions", action.id, "affects", entityIndex],
21599
+ `Action "${action.id}" affects unknown entity "${entityId}"`
21600
+ );
21601
+ }
21602
+ });
21603
+ });
21604
+ const resourcesById = new Map(Object.entries(model.resources));
21605
+ sidebarSurfaces.forEach(({ id, node, path }) => {
21606
+ node.targets?.resources?.forEach((resourceId, resourceIndex) => {
21607
+ if (!resourcesById.has(resourceId)) {
21608
+ addIssue(
21609
+ ctx,
21610
+ [...path, "targets", "resources", resourceIndex],
21611
+ `Sidebar surface "${id}" references unknown resource "${resourceId}"`
21612
+ );
21613
+ }
21614
+ });
21615
+ });
21616
+ const stageIds = /* @__PURE__ */ new Set();
21617
+ const actionIds = new Set(Object.keys(model.actions));
21618
+ const offeringsById = new Map(Object.entries(model.offerings));
21619
+ const ontologyCompilation = compileOrganizationOntology(model);
21620
+ const ontologyIndexByKind = {
21621
+ object: ontologyCompilation.ontology.objectTypes,
21622
+ link: ontologyCompilation.ontology.linkTypes,
21623
+ action: ontologyCompilation.ontology.actionTypes,
21624
+ catalog: ontologyCompilation.ontology.catalogTypes,
21625
+ event: ontologyCompilation.ontology.eventTypes,
21626
+ interface: ontologyCompilation.ontology.interfaceTypes,
21627
+ "value-type": ontologyCompilation.ontology.valueTypes,
21628
+ property: ontologyCompilation.ontology.sharedProperties,
21629
+ group: ontologyCompilation.ontology.groups,
21630
+ surface: ontologyCompilation.ontology.surfaces
21631
+ };
21632
+ const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index2) => Object.keys(index2)));
21633
+ const ontologyReferenceKeyKinds = {
21634
+ valueType: "value-type",
21635
+ catalogType: "catalog",
21636
+ objectType: "object",
21637
+ eventType: "event",
21638
+ actionType: "action",
21639
+ linkType: "link",
21640
+ interfaceType: "interface",
21641
+ propertyType: "property",
21642
+ groupType: "group",
21643
+ surfaceType: "surface",
21644
+ stepCatalog: "catalog"
21645
+ };
21646
+ function validateKnownOntologyReferences(ownerId, value, path, seen = /* @__PURE__ */ new WeakSet()) {
21647
+ if (Array.isArray(value)) {
21648
+ value.forEach((entry, index2) => validateKnownOntologyReferences(ownerId, entry, [...path, index2], seen));
21649
+ return;
21650
+ }
21651
+ if (!isRecord(value)) return;
21652
+ if (seen.has(value)) return;
21653
+ seen.add(value);
21654
+ Object.entries(value).forEach(([key, entry]) => {
21655
+ const expectedKind = ontologyReferenceKeyKinds[key];
21656
+ if (expectedKind !== void 0) {
21657
+ if (typeof entry !== "string") {
21658
+ addIssue(ctx, [...path, key], `Ontology record "${ownerId}" ${key} must be an ontology ID string`);
21659
+ } else if (ontologyIndexByKind[expectedKind][entry] === void 0) {
21660
+ addIssue(
21661
+ ctx,
21662
+ [...path, key],
21663
+ `Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
21664
+ );
21665
+ }
21666
+ }
21667
+ validateKnownOntologyReferences(ownerId, entry, [...path, key], seen);
21668
+ });
21669
+ }
21670
+ for (const { id, record } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
21671
+ validateKnownOntologyReferences(id, record, record.origin.path);
21672
+ }
21673
+ Object.values(model.policies).forEach((policy) => {
21674
+ policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
21675
+ if (!systemsById.has(systemId)) {
21676
+ addIssue(
21677
+ ctx,
21678
+ ["policies", policy.id, "appliesTo", "systemIds", systemIndex],
21679
+ `Policy "${policy.id}" applies to unknown system "${systemId}"`
21680
+ );
21681
+ }
21682
+ });
21683
+ policy.appliesTo.actionIds.forEach((actionId, actionIndex) => {
21684
+ if (!actionsById.has(actionId)) {
21685
+ addIssue(
21686
+ ctx,
21687
+ ["policies", policy.id, "appliesTo", "actionIds", actionIndex],
21688
+ `Policy "${policy.id}" applies to unknown action "${actionId}"`
21689
+ );
21690
+ }
21691
+ });
21692
+ policy.actions.forEach((action, actionIndex) => {
21693
+ if (action.kind === "invoke-action" && !actionsById.has(action.actionId)) {
21694
+ addIssue(
21695
+ ctx,
21696
+ ["policies", policy.id, "actions", actionIndex, "actionId"],
21697
+ `Policy "${policy.id}" invokes unknown action "${action.actionId}"`
21698
+ );
21699
+ }
21700
+ if ((action.kind === "notify-role" || action.kind === "require-approval") && action.roleId !== void 0 && !rolesById.has(action.roleId)) {
21701
+ addIssue(
21702
+ ctx,
21703
+ ["policies", policy.id, "actions", actionIndex, "roleId"],
21704
+ `Policy "${policy.id}" references unknown role "${action.roleId}"`
21705
+ );
21706
+ }
21707
+ });
21708
+ if (policy.trigger.kind === "action-invocation" && !actionsById.has(policy.trigger.actionId)) {
21709
+ addIssue(
21710
+ ctx,
21711
+ ["policies", policy.id, "trigger", "actionId"],
21712
+ `Policy "${policy.id}" references unknown trigger action "${policy.trigger.actionId}"`
21713
+ );
21714
+ }
21715
+ });
21716
+ function knowledgeTargetExists(kind, id) {
21717
+ if (kind === "system") return systemsById.has(id);
21718
+ if (kind === "resource") return resourcesById.has(id);
21719
+ if (kind === "knowledge") return knowledgeById.has(id);
21720
+ if (kind === "stage") return stageIds.has(id);
21721
+ if (kind === "action") return actionIds.has(id);
21722
+ if (kind === "role") return rolesById.has(id);
21723
+ if (kind === "goal") return goalsById.has(id);
21724
+ if (kind === "customer-segment") return segmentsById.has(id);
21725
+ if (kind === "offering") return offeringsById.has(id);
21726
+ if (kind === "ontology") return ontologyIds.has(id);
21727
+ return false;
21728
+ }
21729
+ Object.entries(model.knowledge).forEach(([nodeId, node]) => {
21730
+ node.links.forEach((link, linkIndex) => {
21731
+ if (!knowledgeTargetExists(link.target.kind, link.target.id)) {
21732
+ addIssue(
21733
+ ctx,
21734
+ ["knowledge", nodeId, "links", linkIndex, "target"],
21735
+ `Knowledge node "${node.id}" references unknown ${link.target.kind} target "${link.target.id}"`
21736
+ );
21737
+ }
21738
+ if (!isKnowledgeKindCompatibleWithTarget(node.kind, link.target.kind)) {
21739
+ addIssue(
21740
+ ctx,
21741
+ ["knowledge", nodeId, "links", linkIndex, "target", "kind"],
21742
+ `Knowledge node "${node.id}" kind "${node.kind}" cannot govern ${link.target.kind} targets`
21743
+ );
21744
+ }
21745
+ });
20942
21746
  });
20943
- const resourcesById = collectIds(model.resources.entries, ctx, ["resources", "entries"], "Resource");
20944
- model.resources.entries.forEach((resource, resourceIndex) => {
20945
- if (!systemsById.has(resource.systemId)) {
21747
+ Object.values(model.resources).forEach((resource) => {
21748
+ if (!systemsById.has(resource.systemPath)) {
20946
21749
  addIssue(
20947
21750
  ctx,
20948
- ["resources", "entries", resourceIndex, "systemId"],
20949
- `Resource "${resource.id}" references unknown systemId "${resource.systemId}"`
21751
+ ["resources", resource.id, "systemPath"],
21752
+ `Resource "${resource.id}" references unknown system path "${resource.systemPath}"`
20950
21753
  );
20951
21754
  }
20952
21755
  if (resource.ownerRoleId !== void 0 && !rolesById.has(resource.ownerRoleId)) {
20953
21756
  addIssue(
20954
21757
  ctx,
20955
- ["resources", "entries", resourceIndex, "ownerRoleId"],
21758
+ ["resources", resource.id, "ownerRoleId"],
20956
21759
  `Resource "${resource.id}" references unknown ownerRoleId "${resource.ownerRoleId}"`
20957
21760
  );
20958
21761
  }
20959
21762
  if (resource.kind === "agent" && resource.actsAsRoleId !== void 0 && !rolesById.has(resource.actsAsRoleId)) {
20960
21763
  addIssue(
20961
21764
  ctx,
20962
- ["resources", "entries", resourceIndex, "actsAsRoleId"],
21765
+ ["resources", resource.id, "actsAsRoleId"],
20963
21766
  `Agent resource "${resource.id}" references unknown actsAsRoleId "${resource.actsAsRoleId}"`
20964
21767
  );
20965
21768
  }
20966
21769
  });
20967
- model.roles.roles.forEach((role, roleIndex) => {
21770
+ function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
21771
+ ids?.forEach((ontologyId, ontologyIndex) => {
21772
+ if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
21773
+ addIssue(
21774
+ ctx,
21775
+ ["resources", resourceId, "ontology", bindingKey, ontologyIndex],
21776
+ `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
21777
+ );
21778
+ }
21779
+ });
21780
+ }
21781
+ Object.values(model.resources).forEach((resource) => {
21782
+ const binding = resource.ontology;
21783
+ if (binding === void 0) return;
21784
+ validateResourceOntologyBinding(resource.id, "implements", "action", binding.implements);
21785
+ validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
21786
+ validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
21787
+ validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
21788
+ validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
21789
+ });
21790
+ Object.values(model.roles).forEach((role) => {
20968
21791
  if (role.heldBy === void 0) return;
20969
21792
  asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
20970
21793
  if (holder.kind !== "agent") return;
@@ -20972,7 +21795,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
20972
21795
  if (resource === void 0) {
20973
21796
  addIssue(
20974
21797
  ctx,
20975
- ["roles", "roles", roleIndex, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
21798
+ ["roles", role.id, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
20976
21799
  `Role "${role.id}" references unknown agent holder resource "${holder.agentId}"`
20977
21800
  );
20978
21801
  return;
@@ -20980,364 +21803,818 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
20980
21803
  if (resource.kind !== "agent") {
20981
21804
  addIssue(
20982
21805
  ctx,
20983
- ["roles", "roles", roleIndex, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
21806
+ ["roles", role.id, "heldBy", Array.isArray(role.heldBy) ? holderIndex : "agentId"],
20984
21807
  `Role "${role.id}" agent holder "${holder.agentId}" must reference an agent resource`
20985
21808
  );
20986
21809
  }
20987
21810
  });
20988
21811
  });
20989
- model.knowledge.nodes.forEach((node, nodeIndex) => {
21812
+ Object.entries(model.knowledge).forEach(([nodeId, node]) => {
20990
21813
  node.ownerIds.forEach((roleId, ownerIndex) => {
20991
21814
  if (!rolesById.has(roleId)) {
20992
21815
  addIssue(
20993
21816
  ctx,
20994
- ["knowledge", "nodes", nodeIndex, "ownerIds", ownerIndex],
21817
+ ["knowledge", nodeId, "ownerIds", ownerIndex],
20995
21818
  `Knowledge node "${node.id}" references unknown owner role "${roleId}"`
20996
21819
  );
20997
21820
  }
20998
21821
  });
20999
21822
  });
21823
+ function validateSystemContent(system, systemPath) {
21824
+ const childSystems = system.systems ?? system.subsystems;
21825
+ const childKey = system.systems !== void 0 ? "systems" : "subsystems";
21826
+ const content = system.content;
21827
+ if (content === void 0 || Object.keys(content).length === 0) {
21828
+ if (childSystems !== void 0) {
21829
+ Object.entries(childSystems).forEach(([childLocalId, child]) => {
21830
+ validateSystemContent(child, [...systemPath, childKey, childLocalId]);
21831
+ });
21832
+ }
21833
+ return;
21834
+ }
21835
+ Object.entries(content).forEach(([localId, node]) => {
21836
+ if (node.parentContentId !== void 0 && !(node.parentContentId in content)) {
21837
+ addIssue(
21838
+ ctx,
21839
+ [...systemPath, "content", localId, "parentContentId"],
21840
+ `Content node "${localId}" parentContentId "${node.parentContentId}" does not resolve within the same system`
21841
+ );
21842
+ }
21843
+ });
21844
+ Object.entries(content).forEach(([localId, node]) => {
21845
+ const visited = /* @__PURE__ */ new Set();
21846
+ let currentId = node.parentContentId;
21847
+ while (currentId !== void 0) {
21848
+ if (currentId === localId || visited.has(currentId)) {
21849
+ addIssue(
21850
+ ctx,
21851
+ [...systemPath, "content", localId, "parentContentId"],
21852
+ `Content node "${localId}" has a parentContentId cycle`
21853
+ );
21854
+ break;
21855
+ }
21856
+ visited.add(currentId);
21857
+ currentId = content[currentId]?.parentContentId;
21858
+ }
21859
+ });
21860
+ Object.entries(content).forEach(([localId, node]) => {
21861
+ const childDef = lookupContentType(node.kind, node.type);
21862
+ if (childDef !== void 0 && node.data !== void 0) {
21863
+ const result = childDef.payloadSchema.safeParse(node.data);
21864
+ if (!result.success) {
21865
+ addIssue(
21866
+ ctx,
21867
+ [...systemPath, "content", localId, "data"],
21868
+ `Content node "${localId}" (${node.kind}:${node.type}) data failed payload validation: ${result.error.message}`
21869
+ );
21870
+ }
21871
+ }
21872
+ if (node.parentContentId !== void 0 && childDef !== void 0) {
21873
+ const parentNode = content[node.parentContentId];
21874
+ if (parentNode !== void 0) {
21875
+ const parentDef = lookupContentType(parentNode.kind, parentNode.type);
21876
+ if (parentDef !== void 0 && childDef.kind !== parentDef.kind) {
21877
+ addIssue(
21878
+ ctx,
21879
+ [...systemPath, "content", localId, "parentContentId"],
21880
+ `Content node "${localId}" kind "${childDef.kind}" cannot parent under "${node.parentContentId}" kind "${parentDef.kind}": parentContentId must be same-meta-kind (per L19)`
21881
+ );
21882
+ }
21883
+ }
21884
+ }
21885
+ });
21886
+ if (childSystems !== void 0) {
21887
+ Object.entries(childSystems).forEach(([childLocalId, child]) => {
21888
+ validateSystemContent(child, [...systemPath, childKey, childLocalId]);
21889
+ });
21890
+ }
21891
+ }
21892
+ Object.entries(model.systems).forEach(([systemKey, system]) => {
21893
+ validateSystemContent(system, ["systems", systemKey]);
21894
+ });
21895
+ for (const diagnostic of ontologyCompilation.diagnostics) {
21896
+ addIssue(ctx, diagnostic.path, diagnostic.message);
21897
+ }
21000
21898
  });
21001
21899
 
21002
21900
  // src/organization-model/defaults.ts
21003
- var DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE = {
21004
- nodes: []
21901
+ var DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE = {};
21902
+ var DEFAULT_ORGANIZATION_MODEL_ENTITIES2 = DEFAULT_ORGANIZATION_MODEL_ENTITIES;
21903
+ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
21904
+ sidebar: {
21905
+ primary: {
21906
+ dashboard: {
21907
+ type: "surface",
21908
+ label: "Dashboard",
21909
+ path: "/",
21910
+ surfaceType: "dashboard",
21911
+ icon: "dashboard",
21912
+ order: 10,
21913
+ targets: { systems: ["dashboard"] }
21914
+ },
21915
+ business: {
21916
+ type: "group",
21917
+ label: "Business",
21918
+ icon: "business",
21919
+ order: 20,
21920
+ children: {
21921
+ sales: {
21922
+ type: "surface",
21923
+ label: "Sales",
21924
+ path: "/sales",
21925
+ surfaceType: "page",
21926
+ icon: "sales",
21927
+ order: 10,
21928
+ targets: { systems: ["sales"] }
21929
+ },
21930
+ clients: {
21931
+ type: "surface",
21932
+ label: "Clients",
21933
+ path: "/clients",
21934
+ surfaceType: "list",
21935
+ icon: "projects",
21936
+ order: 20,
21937
+ targets: { systems: ["clients"] }
21938
+ },
21939
+ projects: {
21940
+ type: "surface",
21941
+ label: "Projects",
21942
+ path: "/projects",
21943
+ surfaceType: "page",
21944
+ icon: "projects",
21945
+ order: 30,
21946
+ targets: { systems: ["projects"] }
21947
+ }
21948
+ }
21949
+ },
21950
+ operations: {
21951
+ type: "group",
21952
+ label: "Operations",
21953
+ icon: "operations",
21954
+ order: 30,
21955
+ children: {
21956
+ "operations-overview": {
21957
+ type: "surface",
21958
+ label: "Overview",
21959
+ path: "/operations",
21960
+ surfaceType: "page",
21961
+ order: 10,
21962
+ targets: { systems: ["operations.overview"] }
21963
+ },
21964
+ "operations-systems": {
21965
+ type: "surface",
21966
+ label: "Systems",
21967
+ path: "/operations/systems",
21968
+ surfaceType: "page",
21969
+ order: 20,
21970
+ targets: { systems: ["operations"] }
21971
+ },
21972
+ "operations-resources": {
21973
+ type: "surface",
21974
+ label: "Resources",
21975
+ path: "/operations/resources",
21976
+ surfaceType: "list",
21977
+ order: 30,
21978
+ targets: { systems: ["operations.resources"] }
21979
+ },
21980
+ "operations-command-queue": {
21981
+ type: "surface",
21982
+ label: "Command Queue",
21983
+ path: "/operations/command-queue",
21984
+ surfaceType: "list",
21985
+ order: 40,
21986
+ targets: { systems: ["operations.command-queue"] }
21987
+ },
21988
+ "operations-task-scheduler": {
21989
+ type: "surface",
21990
+ label: "Task Scheduler",
21991
+ path: "/operations/task-scheduler",
21992
+ surfaceType: "list",
21993
+ order: 50,
21994
+ targets: { systems: ["operations.task-scheduler"] }
21995
+ }
21996
+ }
21997
+ },
21998
+ monitoring: {
21999
+ type: "group",
22000
+ label: "Monitoring",
22001
+ icon: "monitoring",
22002
+ order: 40,
22003
+ children: {
22004
+ "monitoring-overview": {
22005
+ type: "surface",
22006
+ label: "Overview",
22007
+ path: "/monitoring",
22008
+ surfaceType: "page",
22009
+ order: 10,
22010
+ targets: { systems: ["monitoring"] }
22011
+ },
22012
+ "monitoring-calendar": {
22013
+ type: "surface",
22014
+ label: "Calendar",
22015
+ path: "/monitoring/calendar",
22016
+ surfaceType: "page",
22017
+ order: 20,
22018
+ targets: { systems: ["monitoring.calendar"] }
22019
+ },
22020
+ "monitoring-activity-log": {
22021
+ type: "surface",
22022
+ label: "Activity Log",
22023
+ path: "/monitoring/activity-log",
22024
+ surfaceType: "list",
22025
+ order: 30,
22026
+ targets: { systems: ["monitoring.activity-log"] }
22027
+ },
22028
+ "monitoring-execution-logs": {
22029
+ type: "surface",
22030
+ label: "Execution Logs",
22031
+ path: "/monitoring/execution-logs",
22032
+ surfaceType: "list",
22033
+ order: 40,
22034
+ targets: { systems: ["monitoring.execution-logs"] }
22035
+ },
22036
+ "monitoring-execution-health": {
22037
+ type: "surface",
22038
+ label: "Execution Health",
22039
+ path: "/monitoring/execution-health",
22040
+ surfaceType: "dashboard",
22041
+ order: 50,
22042
+ targets: { systems: ["monitoring.execution-health"] }
22043
+ },
22044
+ "monitoring-notifications": {
22045
+ type: "surface",
22046
+ label: "Notifications",
22047
+ path: "/monitoring/notifications",
22048
+ surfaceType: "list",
22049
+ order: 60,
22050
+ targets: { systems: ["monitoring.notifications"] }
22051
+ },
22052
+ "monitoring-requests": {
22053
+ type: "surface",
22054
+ label: "Requests",
22055
+ path: "/monitoring/requests",
22056
+ surfaceType: "list",
22057
+ order: 70,
22058
+ targets: { systems: ["monitoring.submitted-requests"] }
22059
+ }
22060
+ }
22061
+ },
22062
+ knowledge: {
22063
+ type: "surface",
22064
+ label: "Knowledge Base",
22065
+ path: "/knowledge",
22066
+ surfaceType: "page",
22067
+ icon: "knowledge",
22068
+ order: 50
22069
+ }
22070
+ },
22071
+ bottom: {
22072
+ settings: {
22073
+ type: "group",
22074
+ label: "Settings",
22075
+ icon: "settings",
22076
+ order: 10,
22077
+ children: {
22078
+ "settings-account": {
22079
+ type: "surface",
22080
+ label: "Account",
22081
+ path: "/settings/account",
22082
+ surfaceType: "settings",
22083
+ order: 10,
22084
+ targets: { systems: ["settings.account"] }
22085
+ },
22086
+ "settings-appearance": {
22087
+ type: "surface",
22088
+ label: "Appearance",
22089
+ path: "/settings/appearance",
22090
+ surfaceType: "settings",
22091
+ order: 20,
22092
+ targets: { systems: ["settings.appearance"] }
22093
+ },
22094
+ "settings-roles": {
22095
+ type: "surface",
22096
+ label: "My Roles",
22097
+ path: "/settings/roles",
22098
+ surfaceType: "settings",
22099
+ order: 30,
22100
+ targets: { systems: ["settings.roles"] }
22101
+ },
22102
+ "settings-organization": {
22103
+ type: "surface",
22104
+ label: "Organization",
22105
+ path: "/settings/organization",
22106
+ surfaceType: "settings",
22107
+ order: 40,
22108
+ targets: { systems: ["settings.organization"] }
22109
+ },
22110
+ "settings-credentials": {
22111
+ type: "surface",
22112
+ label: "Credentials",
22113
+ path: "/settings/credentials",
22114
+ surfaceType: "settings",
22115
+ order: 50,
22116
+ targets: { systems: ["settings.credentials"] }
22117
+ },
22118
+ "settings-api-keys": {
22119
+ type: "surface",
22120
+ label: "API Keys",
22121
+ path: "/settings/api-keys",
22122
+ surfaceType: "settings",
22123
+ order: 60,
22124
+ targets: { systems: ["settings.api-keys"] }
22125
+ },
22126
+ "settings-webhooks": {
22127
+ type: "surface",
22128
+ label: "Webhooks",
22129
+ path: "/settings/webhooks",
22130
+ surfaceType: "settings",
22131
+ order: 70,
22132
+ targets: { systems: ["settings.webhooks"] }
22133
+ },
22134
+ "settings-deployments": {
22135
+ type: "surface",
22136
+ label: "Deployments",
22137
+ path: "/settings/deployments",
22138
+ surfaceType: "settings",
22139
+ order: 80,
22140
+ targets: { systems: ["settings.deployments"] }
22141
+ }
22142
+ }
22143
+ },
22144
+ admin: {
22145
+ type: "group",
22146
+ label: "Admin",
22147
+ icon: "admin",
22148
+ order: 20,
22149
+ children: {
22150
+ "admin-dashboard": {
22151
+ type: "surface",
22152
+ label: "Dashboard",
22153
+ path: "/admin/dashboard",
22154
+ surfaceType: "dashboard",
22155
+ order: 10,
22156
+ targets: { systems: ["admin"] },
22157
+ requiresAdmin: true
22158
+ },
22159
+ "admin-system-health": {
22160
+ type: "surface",
22161
+ label: "System Health",
22162
+ path: "/admin/system-health",
22163
+ surfaceType: "dashboard",
22164
+ order: 20,
22165
+ targets: { systems: ["admin.system-health"] },
22166
+ requiresAdmin: true
22167
+ },
22168
+ "admin-organizations": {
22169
+ type: "surface",
22170
+ label: "Organizations",
22171
+ path: "/admin/organizations",
22172
+ surfaceType: "list",
22173
+ order: 30,
22174
+ targets: { systems: ["admin.organizations"] },
22175
+ requiresAdmin: true
22176
+ },
22177
+ "admin-users": {
22178
+ type: "surface",
22179
+ label: "Users",
22180
+ path: "/admin/users",
22181
+ surfaceType: "list",
22182
+ order: 40,
22183
+ targets: { systems: ["admin.users"] },
22184
+ requiresAdmin: true
22185
+ },
22186
+ "admin-design-showcase": {
22187
+ type: "surface",
22188
+ label: "Design Showcase",
22189
+ path: "/admin/design-showcase",
22190
+ surfaceType: "page",
22191
+ order: 50,
22192
+ targets: { systems: ["admin.design-showcase"] },
22193
+ requiresAdmin: true
22194
+ },
22195
+ "admin-debug": {
22196
+ type: "surface",
22197
+ label: "Debug",
22198
+ path: "/admin/debug",
22199
+ surfaceType: "page",
22200
+ order: 60,
22201
+ targets: { systems: ["admin.debug"] },
22202
+ requiresAdmin: true
22203
+ }
22204
+ }
22205
+ }
22206
+ }
22207
+ }
21005
22208
  };
21006
22209
  var DEFAULT_ORGANIZATION_MODEL = {
21007
22210
  version: 1,
21008
- features: [
21009
- {
22211
+ domainMetadata: DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA,
22212
+ branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
22213
+ navigation: DEFAULT_ORGANIZATION_MODEL_NAVIGATION,
22214
+ identity: DEFAULT_ORGANIZATION_MODEL_IDENTITY,
22215
+ customers: DEFAULT_ORGANIZATION_MODEL_CUSTOMERS,
22216
+ offerings: DEFAULT_ORGANIZATION_MODEL_OFFERINGS,
22217
+ roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
22218
+ goals: DEFAULT_ORGANIZATION_MODEL_GOALS,
22219
+ systems: {
22220
+ dashboard: {
21010
22221
  id: "dashboard",
22222
+ order: 10,
21011
22223
  label: "Dashboard",
21012
22224
  enabled: true,
22225
+ lifecycle: "active",
21013
22226
  path: "/",
21014
- icon: "feature.dashboard",
21015
- uiPosition: "sidebar-primary"
22227
+ icon: "dashboard"
21016
22228
  },
21017
- {
21018
- id: "identity",
21019
- label: "Identity",
21020
- description: "Company identity, positioning, and market context",
21021
- enabled: true,
21022
- color: "indigo"
21023
- },
21024
- {
22229
+ platform: {
21025
22230
  id: "platform",
22231
+ order: 30,
21026
22232
  label: "Platform",
21027
22233
  description: "Elevasis platform architecture, capabilities, and implementation patterns",
21028
22234
  enabled: true,
22235
+ lifecycle: "active",
21029
22236
  color: "cyan",
21030
- icon: "feature.platform"
22237
+ icon: "platform"
21031
22238
  },
21032
- {
22239
+ finance: {
21033
22240
  id: "finance",
22241
+ order: 40,
21034
22242
  label: "Finance",
21035
22243
  description: "Finance operations, accounting, billing, reconciliation, and tax prep",
21036
22244
  enabled: true,
22245
+ lifecycle: "active",
21037
22246
  color: "green",
21038
- icon: "feature.finance"
21039
- },
21040
- {
21041
- id: "business",
21042
- label: "Business",
21043
- description: "Revenue, client relationships, and project delivery",
21044
- enabled: true,
21045
- color: "blue",
21046
- icon: "feature.business",
21047
- uiPosition: "sidebar-primary"
22247
+ icon: "finance"
21048
22248
  },
21049
- {
22249
+ sales: {
21050
22250
  id: "sales",
22251
+ order: 60,
21051
22252
  label: "Sales",
21052
22253
  description: "Revenue workflows and customer acquisition",
21053
22254
  enabled: true,
22255
+ lifecycle: "active",
21054
22256
  color: "blue",
21055
- icon: "feature.sales",
22257
+ icon: "sales",
21056
22258
  path: "/sales"
21057
22259
  },
21058
- {
22260
+ "sales.crm": {
21059
22261
  id: "sales.crm",
22262
+ order: 70,
21060
22263
  label: "CRM",
21061
22264
  description: "Relationship pipeline and deal management",
21062
22265
  enabled: true,
22266
+ lifecycle: "active",
22267
+ actions: Object.values(CRM_ACTION_ENTRIES).map((action) => ({
22268
+ actionId: action.id,
22269
+ intent: "exposes"
22270
+ })),
21063
22271
  color: "blue",
21064
- icon: "feature.crm",
22272
+ icon: "crm",
21065
22273
  path: "/crm"
21066
22274
  },
21067
- {
22275
+ "sales.lead-gen": {
21068
22276
  id: "sales.lead-gen",
22277
+ order: 80,
21069
22278
  label: "Lead Gen",
21070
22279
  description: "Prospecting, qualification, and outreach preparation",
21071
22280
  enabled: true,
22281
+ lifecycle: "active",
22282
+ actions: Object.values(LEAD_GEN_ACTION_ENTRIES).map((action) => ({
22283
+ actionId: action.id,
22284
+ intent: "exposes"
22285
+ })),
21072
22286
  color: "cyan",
21073
- icon: "feature.lead-gen",
22287
+ icon: "lead-gen",
21074
22288
  path: "/lead-gen"
21075
22289
  },
21076
- {
22290
+ projects: {
21077
22291
  id: "projects",
22292
+ order: 90,
21078
22293
  label: "Projects",
21079
22294
  description: "Projects, milestones, and client work execution",
21080
22295
  enabled: true,
22296
+ lifecycle: "active",
21081
22297
  color: "orange",
21082
- icon: "feature.projects",
22298
+ icon: "projects",
21083
22299
  path: "/projects"
21084
22300
  },
21085
- {
22301
+ clients: {
21086
22302
  id: "clients",
22303
+ order: 100,
21087
22304
  label: "Clients",
21088
22305
  description: "Client relationships, accounts, and business context",
21089
22306
  enabled: true,
22307
+ lifecycle: "active",
21090
22308
  color: "orange",
21091
- icon: "feature.projects",
21092
- path: "/business/clients"
22309
+ icon: "projects",
22310
+ path: "/clients"
21093
22311
  },
21094
- {
22312
+ operations: {
21095
22313
  id: "operations",
22314
+ order: 110,
21096
22315
  label: "Operations",
21097
22316
  description: "Operational resources, topology, and orchestration visibility",
21098
22317
  enabled: true,
22318
+ lifecycle: "active",
21099
22319
  color: "violet",
21100
- icon: "feature.operations",
21101
- uiPosition: "sidebar-primary"
22320
+ icon: "operations"
21102
22321
  },
21103
- {
22322
+ "knowledge.command-view": {
21104
22323
  id: "knowledge.command-view",
22324
+ order: 120,
21105
22325
  label: "Command View",
21106
22326
  enabled: true,
22327
+ lifecycle: "active",
21107
22328
  path: "/knowledge/command-view",
21108
22329
  devOnly: true
21109
22330
  },
21110
- {
22331
+ "operations.overview": {
21111
22332
  id: "operations.overview",
22333
+ order: 130,
21112
22334
  label: "Overview",
21113
22335
  enabled: true,
22336
+ lifecycle: "active",
21114
22337
  path: "/operations"
21115
22338
  },
21116
- {
22339
+ "operations.resources": {
21117
22340
  id: "operations.resources",
22341
+ order: 140,
21118
22342
  label: "Resources",
21119
22343
  enabled: true,
22344
+ lifecycle: "active",
21120
22345
  path: "/operations/resources"
21121
22346
  },
21122
- {
22347
+ "operations.command-queue": {
21123
22348
  id: "operations.command-queue",
22349
+ order: 150,
21124
22350
  label: "Command Queue",
21125
22351
  enabled: true,
22352
+ lifecycle: "active",
21126
22353
  path: "/operations/command-queue"
21127
22354
  },
21128
- {
22355
+ "operations.sessions": {
21129
22356
  id: "operations.sessions",
22357
+ order: 160,
21130
22358
  label: "Sessions",
21131
22359
  enabled: false,
22360
+ lifecycle: "deprecated",
21132
22361
  path: "/operations/sessions"
21133
22362
  },
21134
- {
22363
+ "operations.task-scheduler": {
21135
22364
  id: "operations.task-scheduler",
22365
+ order: 170,
21136
22366
  label: "Task Scheduler",
21137
22367
  enabled: true,
22368
+ lifecycle: "active",
21138
22369
  path: "/operations/task-scheduler"
21139
22370
  },
21140
- {
22371
+ monitoring: {
21141
22372
  id: "monitoring",
22373
+ order: 180,
21142
22374
  label: "Monitoring",
21143
22375
  enabled: true,
21144
- uiPosition: "sidebar-primary"
22376
+ lifecycle: "active"
21145
22377
  },
21146
- {
22378
+ "monitoring.calendar": {
21147
22379
  id: "monitoring.calendar",
22380
+ order: 190,
21148
22381
  label: "Calendar",
21149
22382
  description: "Google Calendar events and agenda views",
21150
22383
  enabled: true,
22384
+ lifecycle: "active",
21151
22385
  path: "/monitoring/calendar",
21152
- icon: "feature.calendar"
22386
+ icon: "calendar"
21153
22387
  },
21154
- {
22388
+ "monitoring.activity-log": {
21155
22389
  id: "monitoring.activity-log",
22390
+ order: 200,
21156
22391
  label: "Activity Log",
21157
22392
  enabled: true,
22393
+ lifecycle: "active",
21158
22394
  path: "/monitoring/activity-log"
21159
22395
  },
21160
- {
22396
+ "monitoring.execution-logs": {
21161
22397
  id: "monitoring.execution-logs",
22398
+ order: 210,
21162
22399
  label: "Execution Logs",
21163
22400
  enabled: true,
22401
+ lifecycle: "active",
21164
22402
  path: "/monitoring/execution-logs"
21165
22403
  },
21166
- {
22404
+ "monitoring.execution-health": {
21167
22405
  id: "monitoring.execution-health",
22406
+ order: 220,
21168
22407
  label: "Execution Health",
21169
22408
  enabled: true,
22409
+ lifecycle: "active",
21170
22410
  path: "/monitoring/execution-health"
21171
22411
  },
21172
- {
22412
+ "monitoring.cost-analytics": {
21173
22413
  id: "monitoring.cost-analytics",
22414
+ order: 230,
21174
22415
  label: "Cost Analytics",
21175
22416
  enabled: false,
22417
+ lifecycle: "deprecated",
21176
22418
  path: "/monitoring/cost-analytics"
21177
22419
  },
21178
- {
22420
+ "monitoring.notifications": {
21179
22421
  id: "monitoring.notifications",
22422
+ order: 240,
21180
22423
  label: "Notifications",
21181
22424
  enabled: true,
22425
+ lifecycle: "active",
21182
22426
  path: "/monitoring/notifications"
21183
22427
  },
21184
- {
22428
+ "monitoring.submitted-requests": {
21185
22429
  id: "monitoring.submitted-requests",
22430
+ order: 250,
21186
22431
  label: "Submitted Requests",
21187
22432
  enabled: true,
22433
+ lifecycle: "active",
21188
22434
  path: "/monitoring/requests"
21189
22435
  },
21190
- {
22436
+ settings: {
21191
22437
  id: "settings",
22438
+ order: 260,
21192
22439
  label: "Settings",
21193
22440
  enabled: true,
21194
- icon: "feature.settings",
21195
- uiPosition: "sidebar-bottom"
22441
+ lifecycle: "active",
22442
+ icon: "settings"
21196
22443
  },
21197
- {
22444
+ "settings.account": {
21198
22445
  id: "settings.account",
22446
+ order: 270,
21199
22447
  label: "Account",
21200
22448
  enabled: true,
22449
+ lifecycle: "active",
21201
22450
  path: "/settings/account"
21202
22451
  },
21203
- {
22452
+ "settings.appearance": {
21204
22453
  id: "settings.appearance",
22454
+ order: 280,
21205
22455
  label: "Appearance",
21206
22456
  enabled: true,
22457
+ lifecycle: "active",
21207
22458
  path: "/settings/appearance"
21208
22459
  },
21209
- {
22460
+ "settings.roles": {
21210
22461
  id: "settings.roles",
22462
+ order: 290,
21211
22463
  label: "My Roles",
21212
22464
  enabled: true,
22465
+ lifecycle: "active",
21213
22466
  path: "/settings/roles"
21214
22467
  },
21215
- {
22468
+ "settings.organization": {
21216
22469
  id: "settings.organization",
22470
+ order: 300,
21217
22471
  label: "Organization",
21218
22472
  enabled: true,
22473
+ lifecycle: "active",
21219
22474
  path: "/settings/organization"
21220
22475
  },
21221
- {
22476
+ "settings.credentials": {
21222
22477
  id: "settings.credentials",
22478
+ order: 310,
21223
22479
  label: "Credentials",
21224
22480
  enabled: true,
22481
+ lifecycle: "active",
21225
22482
  path: "/settings/credentials"
21226
22483
  },
21227
- {
22484
+ "settings.api-keys": {
21228
22485
  id: "settings.api-keys",
22486
+ order: 320,
21229
22487
  label: "API Keys",
21230
22488
  enabled: true,
22489
+ lifecycle: "active",
21231
22490
  path: "/settings/api-keys"
21232
22491
  },
21233
- {
22492
+ "settings.webhooks": {
21234
22493
  id: "settings.webhooks",
22494
+ order: 330,
21235
22495
  label: "Webhooks",
21236
22496
  enabled: true,
22497
+ lifecycle: "active",
21237
22498
  path: "/settings/webhooks"
21238
22499
  },
21239
- {
22500
+ "settings.deployments": {
21240
22501
  id: "settings.deployments",
22502
+ order: 340,
21241
22503
  label: "Deployments",
21242
22504
  enabled: true,
22505
+ lifecycle: "active",
21243
22506
  path: "/settings/deployments"
21244
22507
  },
21245
- {
22508
+ admin: {
21246
22509
  id: "admin",
22510
+ order: 350,
21247
22511
  label: "Admin",
21248
22512
  enabled: true,
22513
+ lifecycle: "active",
21249
22514
  path: "/admin",
21250
- icon: "feature.admin",
21251
- uiPosition: "sidebar-bottom",
22515
+ icon: "admin",
21252
22516
  requiresAdmin: true
21253
22517
  },
21254
- {
22518
+ "admin.system-health": {
21255
22519
  id: "admin.system-health",
22520
+ order: 360,
21256
22521
  label: "System Health",
21257
22522
  enabled: true,
22523
+ lifecycle: "active",
21258
22524
  path: "/admin/system-health"
21259
22525
  },
21260
- {
22526
+ "admin.organizations": {
21261
22527
  id: "admin.organizations",
22528
+ order: 370,
21262
22529
  label: "Organizations",
21263
22530
  enabled: true,
22531
+ lifecycle: "active",
21264
22532
  path: "/admin/organizations"
21265
22533
  },
21266
- {
22534
+ "admin.users": {
21267
22535
  id: "admin.users",
22536
+ order: 380,
21268
22537
  label: "Users",
21269
22538
  enabled: true,
22539
+ lifecycle: "active",
21270
22540
  path: "/admin/users"
21271
22541
  },
21272
- {
22542
+ "admin.design-showcase": {
21273
22543
  id: "admin.design-showcase",
22544
+ order: 390,
21274
22545
  label: "Design Showcase",
21275
22546
  enabled: true,
22547
+ lifecycle: "active",
21276
22548
  path: "/admin/design-showcase"
21277
22549
  },
21278
- {
22550
+ "admin.debug": {
21279
22551
  id: "admin.debug",
22552
+ order: 400,
21280
22553
  label: "Debug",
21281
22554
  enabled: true,
22555
+ lifecycle: "active",
21282
22556
  path: "/admin/debug"
21283
22557
  },
21284
- {
22558
+ archive: {
21285
22559
  id: "archive",
22560
+ order: 410,
21286
22561
  label: "Archive",
21287
22562
  enabled: true,
22563
+ lifecycle: "active",
21288
22564
  path: "/archive",
21289
- icon: "feature.archive",
21290
- uiPosition: "sidebar-bottom",
22565
+ icon: "archive",
21291
22566
  devOnly: true
21292
22567
  },
21293
- {
22568
+ "archive.agent-chat": {
21294
22569
  id: "archive.agent-chat",
22570
+ order: 420,
21295
22571
  label: "Agent Chat",
21296
22572
  enabled: true,
22573
+ lifecycle: "active",
21297
22574
  path: "/archive/agent-chat"
21298
22575
  },
21299
- {
22576
+ "archive.execution-runner": {
21300
22577
  id: "archive.execution-runner",
22578
+ order: 430,
21301
22579
  label: "Execution Runner",
21302
22580
  enabled: true,
22581
+ lifecycle: "active",
21303
22582
  path: "/archive/execution-runner"
21304
22583
  },
21305
- {
22584
+ seo: {
21306
22585
  id: "seo",
22586
+ order: 440,
21307
22587
  label: "SEO",
21308
22588
  enabled: false,
22589
+ lifecycle: "deprecated",
21309
22590
  path: "/seo"
21310
22591
  },
21311
- {
22592
+ knowledge: {
21312
22593
  id: "knowledge",
22594
+ order: 450,
21313
22595
  label: "Knowledge",
21314
22596
  description: "Operational knowledge, playbooks, and strategy docs",
21315
22597
  enabled: true,
22598
+ lifecycle: "active",
21316
22599
  color: "teal",
21317
- icon: "feature.knowledge",
21318
- uiPosition: "sidebar-primary"
22600
+ icon: "knowledge"
21319
22601
  },
21320
- {
22602
+ "knowledge.base": {
21321
22603
  id: "knowledge.base",
22604
+ order: 460,
21322
22605
  label: "Knowledge Base",
21323
22606
  enabled: true,
22607
+ lifecycle: "active",
21324
22608
  path: "/knowledge"
21325
22609
  }
21326
- ],
21327
- branding: DEFAULT_ORGANIZATION_MODEL_BRANDING,
21328
- navigation: { surfaces: [], groups: [] },
21329
- sales: DEFAULT_ORGANIZATION_MODEL_SALES,
21330
- prospecting: DEFAULT_ORGANIZATION_MODEL_PROSPECTING,
21331
- projects: DEFAULT_ORGANIZATION_MODEL_PROJECTS,
21332
- identity: DEFAULT_ORGANIZATION_MODEL_IDENTITY,
21333
- customers: DEFAULT_ORGANIZATION_MODEL_CUSTOMERS,
21334
- offerings: DEFAULT_ORGANIZATION_MODEL_OFFERINGS,
21335
- roles: DEFAULT_ORGANIZATION_MODEL_ROLES,
21336
- goals: DEFAULT_ORGANIZATION_MODEL_GOALS,
21337
- systems: DEFAULT_ORGANIZATION_MODEL_SYSTEMS,
22610
+ },
22611
+ ontology: DEFAULT_ONTOLOGY_SCOPE,
21338
22612
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
21339
- statuses: DEFAULT_ORGANIZATION_MODEL_STATUSES,
21340
- operations: DEFAULT_ORGANIZATION_MODEL_OPERATIONS,
22613
+ actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
22614
+ entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
22615
+ policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
22616
+ // Phase 4 (D1): statuses top-level field removed; bridge status mirrors may
22617
+ // still project from System.content, but primary authoring belongs in ontology.
21341
22618
  knowledge: DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE
21342
22619
  };
21343
22620
 
@@ -21345,6 +22622,31 @@ var DEFAULT_ORGANIZATION_MODEL = {
21345
22622
  function isPlainObject(value) {
21346
22623
  return typeof value === "object" && value !== null && !Array.isArray(value);
21347
22624
  }
22625
+ function collectNestedSystemPaths(systems, prefix = "") {
22626
+ const paths = /* @__PURE__ */ new Set();
22627
+ for (const [key, value] of Object.entries(systems)) {
22628
+ if (!isPlainObject(value)) continue;
22629
+ const path = prefix ? `${prefix}.${key}` : key;
22630
+ for (const childKey of ["systems", "subsystems"]) {
22631
+ const childSystems = value[childKey];
22632
+ if (!isPlainObject(childSystems)) continue;
22633
+ for (const childPath of collectNestedSystemPaths(childSystems, path)) {
22634
+ paths.add(childPath);
22635
+ }
22636
+ }
22637
+ if (prefix !== "") {
22638
+ paths.add(path);
22639
+ }
22640
+ }
22641
+ return paths;
22642
+ }
22643
+ function pruneFlatSystemDescendantCollisions(base, override) {
22644
+ const result = { ...base };
22645
+ for (const nestedPath of collectNestedSystemPaths(override)) {
22646
+ delete result[nestedPath];
22647
+ }
22648
+ return result;
22649
+ }
21348
22650
  function deepMerge2(base, override) {
21349
22651
  if (override === void 0) {
21350
22652
  return base;
@@ -21359,20 +22661,17 @@ function deepMerge2(base, override) {
21359
22661
  for (const [key, value] of Object.entries(override)) {
21360
22662
  if (value === void 0) continue;
21361
22663
  const existing = result[key];
22664
+ if (key === "systems" && isPlainObject(existing) && isPlainObject(value)) {
22665
+ result[key] = deepMerge2(pruneFlatSystemDescendantCollisions(existing, value), value);
22666
+ continue;
22667
+ }
21362
22668
  result[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge2(existing, value) : value;
21363
22669
  }
21364
22670
  return result;
21365
22671
  }
21366
- function resolveOrganizationModel(override, organizationId) {
21367
- const merged = deepMerge2(DEFAULT_ORGANIZATION_MODEL, override);
21368
- const model = OrganizationModelSchema.parse(merged);
21369
- if (!model.sales?.pipelines || model.sales.pipelines.length === 0) {
21370
- const orgLabel = "Organization";
21371
- throw new Error(
21372
- `${orgLabel} has no sales pipeline configuration. This indicates an incomplete provisioning state. Run org provisioning to seed defaults.`
21373
- );
21374
- }
21375
- return model;
22672
+ function resolveOrganizationModel(override, organizationIdOrOptions, options) {
22673
+ const merged = deepMerge2(DEFAULT_ORGANIZATION_MODEL, override) ;
22674
+ return OrganizationModelSchema.parse(merged);
21376
22675
  }
21377
22676
 
21378
22677
  // src/test-utils/organization-model.ts