@elevasis/core 0.23.0 → 0.24.1

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 (243) hide show
  1. package/dist/index.d.ts +4343 -2690
  2. package/dist/index.js +1101 -156
  3. package/dist/knowledge/index.d.ts +574 -210
  4. package/dist/knowledge/index.js +104 -1
  5. package/dist/organization-model/index.d.ts +4343 -2690
  6. package/dist/organization-model/index.js +1101 -156
  7. package/dist/test-utils/index.d.ts +483 -109
  8. package/dist/test-utils/index.js +904 -144
  9. package/package.json +3 -3
  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 -12
  13. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +2137 -2093
  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 +1492 -1497
  37. package/src/business/acquisition/build-templates.test.ts +240 -240
  38. package/src/business/acquisition/build-templates.ts +98 -98
  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 -153
  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 -396
  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 +195 -197
  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 +32 -32
  123. package/src/knowledge/__tests__/queries.test.ts +626 -535
  124. package/src/knowledge/format.ts +99 -99
  125. package/src/knowledge/index.ts +5 -5
  126. package/src/knowledge/published.ts +5 -5
  127. package/src/knowledge/queries.ts +269 -218
  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 -149
  131. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -210
  132. package/src/organization-model/__tests__/defaults.test.ts +168 -168
  133. package/src/organization-model/__tests__/domains/actions.test.ts +78 -56
  134. package/src/organization-model/__tests__/domains/customers.test.ts +299 -299
  135. package/src/organization-model/__tests__/domains/entities.test.ts +56 -56
  136. package/src/organization-model/__tests__/domains/goals.test.ts +493 -493
  137. package/src/organization-model/__tests__/domains/identity.test.ts +280 -280
  138. package/src/organization-model/__tests__/domains/navigation.test.ts +268 -268
  139. package/src/organization-model/__tests__/domains/offerings.test.ts +414 -414
  140. package/src/organization-model/__tests__/domains/policies.test.ts +323 -323
  141. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +293 -293
  142. package/src/organization-model/__tests__/domains/resources.test.ts +387 -277
  143. package/src/organization-model/__tests__/domains/roles.test.ts +463 -463
  144. package/src/organization-model/__tests__/domains/statuses.test.ts +246 -246
  145. package/src/organization-model/__tests__/domains/systems.test.ts +209 -209
  146. package/src/organization-model/__tests__/domains/topology.test.ts +188 -0
  147. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +362 -361
  148. package/src/organization-model/__tests__/foundation.test.ts +77 -77
  149. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -144
  150. package/src/organization-model/__tests__/graph.test.ts +1312 -862
  151. package/src/organization-model/__tests__/icons.test.ts +10 -1
  152. package/src/organization-model/__tests__/knowledge.test.ts +251 -15
  153. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -438
  154. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -591
  155. package/src/organization-model/__tests__/prospecting-ssot.test.ts +103 -103
  156. package/src/organization-model/__tests__/recursive-system-schema.test.ts +535 -506
  157. package/src/organization-model/__tests__/resolve.test.ts +274 -164
  158. package/src/organization-model/__tests__/schema.test.ts +844 -301
  159. package/src/organization-model/__tests__/surface-projection.test.ts +284 -284
  160. package/src/organization-model/catalogs/lead-gen.ts +144 -144
  161. package/src/organization-model/content-kinds/config.ts +36 -36
  162. package/src/organization-model/content-kinds/index.ts +76 -72
  163. package/src/organization-model/content-kinds/pipeline.ts +68 -68
  164. package/src/organization-model/content-kinds/registry.ts +44 -44
  165. package/src/organization-model/content-kinds/status.ts +71 -71
  166. package/src/organization-model/content-kinds/template.ts +83 -83
  167. package/src/organization-model/content-kinds/types.ts +117 -117
  168. package/src/organization-model/contracts.ts +27 -27
  169. package/src/organization-model/defaults.ts +42 -50
  170. package/src/organization-model/domains/actions.ts +333 -239
  171. package/src/organization-model/domains/customers.ts +78 -78
  172. package/src/organization-model/domains/entities.ts +144 -144
  173. package/src/organization-model/domains/goals.ts +83 -83
  174. package/src/organization-model/domains/knowledge.ts +117 -101
  175. package/src/organization-model/domains/navigation.ts +139 -139
  176. package/src/organization-model/domains/offerings.ts +71 -71
  177. package/src/organization-model/domains/policies.ts +102 -102
  178. package/src/organization-model/domains/projects.ts +14 -14
  179. package/src/organization-model/domains/prospecting.ts +395 -395
  180. package/src/organization-model/domains/resources.ts +202 -124
  181. package/src/organization-model/domains/roles.ts +96 -96
  182. package/src/organization-model/domains/sales.test.ts +218 -218
  183. package/src/organization-model/domains/sales.ts +380 -380
  184. package/src/organization-model/domains/shared.ts +63 -63
  185. package/src/organization-model/domains/statuses.ts +339 -339
  186. package/src/organization-model/domains/systems.ts +217 -172
  187. package/src/organization-model/domains/topology.ts +261 -0
  188. package/src/organization-model/foundation.ts +75 -75
  189. package/src/organization-model/graph/build.ts +1043 -867
  190. package/src/organization-model/graph/index.ts +4 -4
  191. package/src/organization-model/graph/link.ts +10 -10
  192. package/src/organization-model/graph/schema.ts +75 -68
  193. package/src/organization-model/graph/types.ts +71 -64
  194. package/src/organization-model/helpers.ts +289 -241
  195. package/src/organization-model/icons.ts +78 -66
  196. package/src/organization-model/index.ts +128 -125
  197. package/src/organization-model/migration-helpers.ts +247 -244
  198. package/src/organization-model/ontology.ts +658 -0
  199. package/src/organization-model/organization-graph.mdx +110 -90
  200. package/src/organization-model/organization-model.mdx +225 -213
  201. package/src/organization-model/published.ts +299 -222
  202. package/src/organization-model/resolve.ts +146 -91
  203. package/src/organization-model/schema.ts +818 -659
  204. package/src/organization-model/surface-projection.ts +212 -212
  205. package/src/organization-model/types.ts +179 -155
  206. package/src/platform/api/types.ts +38 -38
  207. package/src/platform/constants/versions.ts +3 -3
  208. package/src/platform/index.ts +23 -23
  209. package/src/platform/registry/__tests__/command-view.test.ts +10 -10
  210. package/src/platform/registry/__tests__/resource-link.test.ts +35 -35
  211. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +20 -20
  212. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -245
  213. package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2053
  214. package/src/platform/registry/__tests__/validation.test.ts +1444 -1259
  215. package/src/platform/registry/command-view.ts +10 -10
  216. package/src/platform/registry/index.ts +103 -103
  217. package/src/platform/registry/resource-link.ts +32 -32
  218. package/src/platform/registry/resource-registry.ts +886 -886
  219. package/src/platform/registry/serialization.ts +295 -295
  220. package/src/platform/registry/serialized-types.ts +166 -166
  221. package/src/platform/registry/stats-types.ts +68 -68
  222. package/src/platform/registry/types.ts +425 -425
  223. package/src/platform/registry/validation.ts +876 -684
  224. package/src/platform/utils/__tests__/validation.test.ts +1084 -1084
  225. package/src/platform/utils/validation.ts +425 -425
  226. package/src/projects/api-schemas.test.ts +39 -39
  227. package/src/projects/api-schemas.ts +291 -291
  228. package/src/reference/_generated/contracts.md +2136 -2093
  229. package/src/reference/glossary.md +76 -76
  230. package/src/scaffold-registry/__tests__/index.test.ts +206 -206
  231. package/src/scaffold-registry/__tests__/schema.test.ts +166 -166
  232. package/src/scaffold-registry/index.ts +392 -392
  233. package/src/scaffold-registry/schema.ts +243 -243
  234. package/src/server.ts +289 -289
  235. package/src/supabase/database.types.ts +3 -0
  236. package/src/test-utils/README.md +37 -37
  237. package/src/test-utils/entities.ts +108 -108
  238. package/src/test-utils/fixtures/memberships.ts +82 -82
  239. package/src/test-utils/index.ts +12 -12
  240. package/src/test-utils/organization-model.ts +65 -65
  241. package/src/test-utils/published.ts +6 -6
  242. package/src/test-utils/rls/RLSTestContext.ts +588 -588
  243. package/src/test-utils/test-utils.test.ts +44 -44
@@ -1,6 +1,407 @@
1
1
  import { z } from 'zod';
2
2
 
3
- // src/organization-model/schema.ts
3
+ // src/organization-model/ontology.ts
4
+ var OntologyKindSchema = z.enum([
5
+ "object",
6
+ "link",
7
+ "action",
8
+ "catalog",
9
+ "event",
10
+ "interface",
11
+ "value-type",
12
+ "property",
13
+ "group",
14
+ "surface"
15
+ ]);
16
+ var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
17
+ var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
18
+ var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
19
+ var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
20
+ var OntologyIdSchema = z.string().trim().min(1).max(300).regex(
21
+ ONTOLOGY_ID_REGEX,
22
+ "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
23
+ );
24
+ function parseOntologyId(id) {
25
+ const normalized = OntologyIdSchema.parse(id);
26
+ const match = ONTOLOGY_ID_REGEX.exec(normalized);
27
+ if (match === null) {
28
+ throw new Error(`Invalid ontology ID "${id}"`);
29
+ }
30
+ return {
31
+ id: normalized,
32
+ scope: match[1],
33
+ kind: match[2],
34
+ localId: match[3],
35
+ isGlobal: match[1] === "global"
36
+ };
37
+ }
38
+ function formatOntologyId(input) {
39
+ return OntologyIdSchema.parse(`${input.scope}:${input.kind}/${input.localId}`);
40
+ }
41
+ var OntologyReferenceListSchema = z.array(OntologyIdSchema).default([]).optional();
42
+ var OntologyRecordBaseSchema = z.object({
43
+ id: OntologyIdSchema,
44
+ label: z.string().trim().min(1).max(160).optional(),
45
+ description: z.string().trim().min(1).max(2e3).optional(),
46
+ ownerSystemId: z.string().trim().min(1).max(200).optional(),
47
+ aliases: z.array(OntologyIdSchema).optional()
48
+ }).passthrough();
49
+ var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
50
+ properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
51
+ storage: z.record(z.string(), z.unknown()).optional()
52
+ });
53
+ var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
54
+ from: OntologyIdSchema,
55
+ to: OntologyIdSchema,
56
+ cardinality: z.string().trim().min(1).max(80).optional(),
57
+ via: z.string().trim().min(1).max(255).optional()
58
+ });
59
+ var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
60
+ actsOn: OntologyReferenceListSchema,
61
+ input: z.record(z.string().trim().min(1).max(200), z.unknown()).optional(),
62
+ effects: z.array(z.record(z.string(), z.unknown())).optional()
63
+ });
64
+ var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
65
+ kind: z.string().trim().min(1).max(120).optional(),
66
+ appliesTo: OntologyIdSchema.optional(),
67
+ entries: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
68
+ });
69
+ var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
70
+ payload: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
71
+ });
72
+ var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
73
+ properties: z.record(z.string().trim().min(1).max(200), z.unknown()).optional()
74
+ });
75
+ var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
76
+ primitive: z.string().trim().min(1).max(120).optional()
77
+ });
78
+ var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
79
+ valueType: OntologyIdSchema.optional(),
80
+ searchable: z.boolean().optional(),
81
+ pii: z.boolean().optional()
82
+ });
83
+ var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
84
+ members: OntologyReferenceListSchema
85
+ });
86
+ var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
87
+ route: z.string().trim().min(1).max(500).optional()
88
+ });
89
+ var OntologyScopeSchema = z.object({
90
+ objectTypes: z.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
91
+ linkTypes: z.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
92
+ actionTypes: z.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
93
+ catalogTypes: z.record(OntologyIdSchema, OntologyCatalogTypeSchema).default({}).optional(),
94
+ eventTypes: z.record(OntologyIdSchema, OntologyEventTypeSchema).default({}).optional(),
95
+ interfaceTypes: z.record(OntologyIdSchema, OntologyInterfaceTypeSchema).default({}).optional(),
96
+ valueTypes: z.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
97
+ sharedProperties: z.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
98
+ groups: z.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
99
+ surfaces: z.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
100
+ }).default({});
101
+ var DEFAULT_ONTOLOGY_SCOPE = {
102
+ valueTypes: {
103
+ "global:value-type/uuid": {
104
+ id: "global:value-type/uuid",
105
+ label: "UUID",
106
+ primitive: "string"
107
+ },
108
+ "global:value-type/text": {
109
+ id: "global:value-type/text",
110
+ label: "Text",
111
+ primitive: "string"
112
+ },
113
+ "global:value-type/url": {
114
+ id: "global:value-type/url",
115
+ label: "URL",
116
+ primitive: "string"
117
+ },
118
+ "global:value-type/email": {
119
+ id: "global:value-type/email",
120
+ label: "Email",
121
+ primitive: "string"
122
+ }
123
+ }
124
+ };
125
+ var SCOPE_KIND = {
126
+ objectTypes: "object",
127
+ linkTypes: "link",
128
+ actionTypes: "action",
129
+ catalogTypes: "catalog",
130
+ eventTypes: "event",
131
+ interfaceTypes: "interface",
132
+ valueTypes: "value-type",
133
+ sharedProperties: "property",
134
+ groups: "group",
135
+ surfaces: "surface"
136
+ };
137
+ var SCOPE_KEYS = Object.keys(SCOPE_KIND);
138
+ function ontologyGraphNodeId(id) {
139
+ return `ontology:${OntologyIdSchema.parse(id)}`;
140
+ }
141
+ function ontologyIdFromGraphNodeId(nodeId) {
142
+ if (!nodeId.startsWith("ontology:")) return void 0;
143
+ const result = OntologyIdSchema.safeParse(nodeId.slice("ontology:".length));
144
+ return result.success ? result.data : void 0;
145
+ }
146
+ function isOntologyGraphNodeId(nodeId) {
147
+ return ontologyIdFromGraphNodeId(nodeId) !== void 0;
148
+ }
149
+ function listResolvedOntologyRecords(index) {
150
+ return SCOPE_KEYS.flatMap((scopeKey) => {
151
+ const kind = SCOPE_KIND[scopeKey];
152
+ return Object.entries(index[scopeKey]).sort(([leftId], [rightId]) => leftId.localeCompare(rightId)).map(([id, record]) => ({
153
+ id,
154
+ kind,
155
+ record
156
+ }));
157
+ });
158
+ }
159
+ function originFromContext(context) {
160
+ return {
161
+ kind: context.kind,
162
+ source: context.source,
163
+ path: context.path,
164
+ ...context.systemPath !== void 0 ? { systemPath: context.systemPath } : {},
165
+ ...context.legacyId !== void 0 ? { legacyId: context.legacyId } : {}
166
+ };
167
+ }
168
+ function createEmptyIndex() {
169
+ return {
170
+ objectTypes: {},
171
+ linkTypes: {},
172
+ actionTypes: {},
173
+ catalogTypes: {},
174
+ eventTypes: {},
175
+ interfaceTypes: {},
176
+ valueTypes: {},
177
+ sharedProperties: {},
178
+ groups: {},
179
+ surfaces: {}
180
+ };
181
+ }
182
+ function sortResolvedOntologyIndex(index) {
183
+ const sorted = createEmptyIndex();
184
+ for (const scopeKey of SCOPE_KEYS) {
185
+ const target = sorted[scopeKey];
186
+ for (const [id, record] of Object.entries(index[scopeKey]).sort(
187
+ ([leftId], [rightId]) => leftId.localeCompare(rightId)
188
+ )) {
189
+ target[id] = record;
190
+ }
191
+ }
192
+ return sorted;
193
+ }
194
+ function childSystemsOf(system) {
195
+ return system.systems ?? system.subsystems ?? {};
196
+ }
197
+ function addRecord(index, diagnostics, sourcesById, scopeKey, record, context) {
198
+ let parsed;
199
+ try {
200
+ parsed = parseOntologyId(record.id);
201
+ } catch {
202
+ diagnostics.push({
203
+ code: "invalid_ontology_id",
204
+ message: `Invalid ontology ID "${record.id}" from ${context.source} at ${context.path.join(".")}`,
205
+ id: record.id,
206
+ path: context.path,
207
+ source: context.source,
208
+ origin: originFromContext(context)
209
+ });
210
+ return;
211
+ }
212
+ const expectedKind = SCOPE_KIND[scopeKey];
213
+ if (parsed.kind !== expectedKind) {
214
+ diagnostics.push({
215
+ code: "ontology_kind_mismatch",
216
+ message: `Ontology ID "${record.id}" has kind "${parsed.kind}" but was authored in ${scopeKey} (${expectedKind}) at ${context.path.join(".")}`,
217
+ id: record.id,
218
+ path: context.path,
219
+ source: context.source,
220
+ origin: originFromContext(context)
221
+ });
222
+ return;
223
+ }
224
+ const existing = sourcesById.get(parsed.id);
225
+ if (existing !== void 0) {
226
+ diagnostics.push({
227
+ code: "duplicate_ontology_id",
228
+ message: `Duplicate ontology ID "${parsed.id}" from ${context.source} at ${context.path.join(".")} conflicts with ${existing.source} at ${existing.path.join(".")}`,
229
+ id: parsed.id,
230
+ path: context.path,
231
+ source: context.source,
232
+ origin: originFromContext(context),
233
+ existingSource: existing.source,
234
+ existingOrigin: originFromContext(existing)
235
+ });
236
+ return;
237
+ }
238
+ sourcesById.set(parsed.id, context);
239
+ index[scopeKey][parsed.id] = {
240
+ ...record,
241
+ origin: originFromContext(context)
242
+ };
243
+ }
244
+ function addScope(index, diagnostics, sourcesById, scope, source, path) {
245
+ if (scope === void 0) return;
246
+ for (const scopeKey of SCOPE_KEYS) {
247
+ const records = scope[scopeKey] ?? {};
248
+ for (const [key, record] of Object.entries(records)) {
249
+ addRecord(index, diagnostics, sourcesById, scopeKey, record, {
250
+ source,
251
+ path: [...path, scopeKey, key],
252
+ kind: "authored",
253
+ systemPath: source.startsWith("system:") ? source.slice("system:".length, -".ontology".length) : void 0
254
+ });
255
+ }
256
+ }
257
+ }
258
+ function legacyObjectId(entity) {
259
+ return formatOntologyId({ scope: entity.ownedBySystemId, kind: "object", localId: entity.id });
260
+ }
261
+ function legacyActionOwner(action, entities) {
262
+ const firstAffectedEntityId = action.affects?.find((entityId) => entities[entityId] !== void 0);
263
+ if (firstAffectedEntityId !== void 0) {
264
+ return entities[firstAffectedEntityId].ownedBySystemId;
265
+ }
266
+ if (typeof action.scope === "object") {
267
+ return action.scope.domain;
268
+ }
269
+ return "global";
270
+ }
271
+ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
272
+ for (const entity of Object.values(entities)) {
273
+ const objectType = {
274
+ id: legacyObjectId(entity),
275
+ label: entity.label,
276
+ description: entity.description,
277
+ ownerSystemId: entity.ownedBySystemId,
278
+ ...entity.table !== void 0 ? {
279
+ storage: {
280
+ kind: "table",
281
+ table: entity.table
282
+ }
283
+ } : {},
284
+ ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
285
+ ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
286
+ };
287
+ addRecord(index, diagnostics, sourcesById, "objectTypes", objectType, {
288
+ source: "legacy.entities",
289
+ path: ["entities", entity.id],
290
+ kind: "projected",
291
+ systemPath: entity.ownedBySystemId,
292
+ legacyId: entity.id
293
+ });
294
+ entity.links?.forEach((link, linkIndex) => {
295
+ const targetEntity = entities[link.toEntity];
296
+ if (targetEntity === void 0) return;
297
+ const linkType = {
298
+ id: formatOntologyId({
299
+ scope: entity.ownedBySystemId,
300
+ kind: "link",
301
+ localId: `${entity.id}-${link.toEntity}-${linkIndex}`
302
+ }),
303
+ label: link.label ?? link.kind,
304
+ ownerSystemId: entity.ownedBySystemId,
305
+ from: legacyObjectId(entity),
306
+ to: legacyObjectId(targetEntity),
307
+ cardinality: link.kind,
308
+ ...link.via !== void 0 ? { via: link.via } : {}
309
+ };
310
+ addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
311
+ source: "legacy.entities.links",
312
+ path: ["entities", entity.id, "links", linkIndex],
313
+ kind: "projected",
314
+ systemPath: entity.ownedBySystemId,
315
+ legacyId: `${entity.id}.links.${linkIndex}`
316
+ });
317
+ });
318
+ }
319
+ }
320
+ function addLegacyActionProjections(index, diagnostics, sourcesById, actions, entities) {
321
+ for (const action of Object.values(actions)) {
322
+ const ownerSystemId = legacyActionOwner(action, entities);
323
+ const actionType = {
324
+ id: formatOntologyId({ scope: ownerSystemId, kind: "action", localId: action.id }),
325
+ label: action.label,
326
+ description: action.description,
327
+ ownerSystemId,
328
+ actsOn: action.affects?.map((entityId) => entities[entityId] ? legacyObjectId(entities[entityId]) : void 0).filter((id) => id !== void 0),
329
+ ...action.resourceId !== void 0 ? { resourceId: action.resourceId } : {},
330
+ ...action.invocations !== void 0 ? { invocations: action.invocations } : {},
331
+ ...action.lifecycle !== void 0 ? { lifecycle: action.lifecycle } : {},
332
+ legacyActionId: action.id
333
+ };
334
+ addRecord(index, diagnostics, sourcesById, "actionTypes", actionType, {
335
+ source: "legacy.actions",
336
+ path: ["actions", action.id],
337
+ kind: "projected",
338
+ systemPath: ownerSystemId,
339
+ legacyId: action.id
340
+ });
341
+ }
342
+ }
343
+ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, schemaPath) {
344
+ const content = system.content ?? {};
345
+ for (const [localId, node] of Object.entries(content)) {
346
+ if (node.kind !== "schema") continue;
347
+ const entries = Object.fromEntries(
348
+ Object.entries(content).filter(([, candidate]) => candidate.parentContentId === localId).map(([entryId, candidate]) => [
349
+ entryId,
350
+ {
351
+ label: candidate.label ?? entryId,
352
+ type: candidate.type,
353
+ ...candidate.description !== void 0 ? { description: candidate.description } : {},
354
+ ...candidate.data !== void 0 ? candidate.data : {}
355
+ }
356
+ ])
357
+ );
358
+ const catalogType = {
359
+ id: formatOntologyId({ scope: systemPath, kind: "catalog", localId }),
360
+ label: node.label ?? localId,
361
+ description: node.description,
362
+ ownerSystemId: systemPath,
363
+ kind: node.type,
364
+ ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
365
+ ...Object.keys(entries).length > 0 ? { entries } : {},
366
+ ...node.data !== void 0 ? { data: node.data } : {}
367
+ };
368
+ addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
369
+ source: "legacy.system.content",
370
+ path: [...schemaPath, "content", localId],
371
+ kind: "projected",
372
+ systemPath,
373
+ legacyId: `${systemPath}:${localId}`
374
+ });
375
+ }
376
+ }
377
+ function addSystemScopes(index, diagnostics, sourcesById, systems, prefix, schemaPath) {
378
+ for (const [key, system] of Object.entries(systems)) {
379
+ const systemPath = prefix ? `${prefix}.${key}` : key;
380
+ const currentPath = [...schemaPath, key];
381
+ addScope(index, diagnostics, sourcesById, system.ontology, `system:${systemPath}.ontology`, [
382
+ ...currentPath,
383
+ "ontology"
384
+ ]);
385
+ addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, currentPath);
386
+ addSystemScopes(index, diagnostics, sourcesById, childSystemsOf(system), systemPath, [
387
+ ...currentPath,
388
+ system.systems !== void 0 ? "systems" : "subsystems"
389
+ ]);
390
+ }
391
+ }
392
+ function compileOrganizationOntology(model) {
393
+ const ontology = createEmptyIndex();
394
+ const diagnostics = [];
395
+ const sourcesById = /* @__PURE__ */ new Map();
396
+ addScope(ontology, diagnostics, sourcesById, model.ontology, "organization.ontology", ["ontology"]);
397
+ addSystemScopes(ontology, diagnostics, sourcesById, model.systems ?? {}, "", ["systems"]);
398
+ addLegacyEntityProjections(ontology, diagnostics, sourcesById, model.entities ?? {});
399
+ addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
400
+ return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
401
+ }
402
+ function getOntologyDiagnostics(model) {
403
+ return compileOrganizationOntology(model).diagnostics;
404
+ }
4
405
 
5
406
  // src/organization-model/content-kinds/registry.ts
6
407
  function defineContentType(def) {
@@ -186,73 +587,78 @@ function lookupContentType(kind, type) {
186
587
  return CONTENT_KIND_REGISTRY[key];
187
588
  }
188
589
  var ORGANIZATION_MODEL_ICON_TOKENS = [
189
- "nav.dashboard",
190
- "nav.calendar",
191
- "nav.sales",
192
- "nav.crm",
193
- "nav.lead-gen",
194
- "nav.projects",
195
- "nav.operations",
196
- "nav.monitoring",
197
- "nav.knowledge",
198
- "nav.settings",
199
- "nav.admin",
200
- "nav.archive",
201
- "knowledge.playbook",
202
- "knowledge.strategy",
203
- "knowledge.reference",
204
- "feature.dashboard",
205
- "feature.calendar",
206
- "feature.business",
207
- "feature.sales",
208
- "feature.crm",
209
- "feature.finance",
210
- "feature.lead-gen",
211
- "feature.platform",
212
- "feature.projects",
213
- "feature.operations",
214
- "feature.knowledge",
215
- "feature.monitoring",
216
- "feature.settings",
217
- "feature.admin",
218
- "feature.archive",
219
- "feature.seo",
220
- "resource.agent",
221
- "resource.workflow",
222
- "resource.integration",
223
- "resource.database",
224
- "resource.user",
225
- "resource.team",
226
- "integration.gmail",
227
- "integration.google-sheets",
228
- "integration.attio",
229
- "surface.dashboard",
230
- "surface.calendar",
231
- "surface.overview",
232
- "surface.command-view",
233
- "surface.command-queue",
234
- "surface.pipeline",
235
- "surface.lists",
236
- "surface.resources",
237
- "surface.settings",
238
- "status.success",
239
- "status.error",
240
- "status.warning",
241
- "status.info",
242
- "status.pending",
243
- "action.approve",
244
- "action.reject",
245
- "action.retry",
246
- "action.edit",
247
- "action.view",
248
- "action.launch",
249
- "action.message",
250
- "action.escalate",
251
- "action.promote",
252
- "action.submit",
253
- "action.email"
590
+ // Navigation / app areas
591
+ "dashboard",
592
+ "calendar",
593
+ "sales",
594
+ "crm",
595
+ "lead-gen",
596
+ "projects",
597
+ "operations",
598
+ "monitoring",
599
+ "knowledge",
600
+ "settings",
601
+ "admin",
602
+ "archive",
603
+ "business",
604
+ "finance",
605
+ "platform",
606
+ "seo",
607
+ // Knowledge kinds
608
+ "playbook",
609
+ "strategy",
610
+ "reference",
611
+ // Resource kinds
612
+ "agent",
613
+ "workflow",
614
+ "integration",
615
+ "database",
616
+ "user",
617
+ "team",
618
+ // Integration specifics
619
+ "gmail",
620
+ "google-sheets",
621
+ "attio",
622
+ // Surface / UI views
623
+ "overview",
624
+ "command-view",
625
+ "command-queue",
626
+ "pipeline",
627
+ "lists",
628
+ "resources",
629
+ // Actions
630
+ "approve",
631
+ "reject",
632
+ "retry",
633
+ "edit",
634
+ "view",
635
+ "launch",
636
+ "message",
637
+ "escalate",
638
+ "promote",
639
+ "submit",
640
+ "email",
641
+ // Status
642
+ "success",
643
+ "error",
644
+ "warning",
645
+ "info",
646
+ "pending",
647
+ // OM / UI group icons
648
+ "bolt",
649
+ "building",
650
+ "briefcase",
651
+ "apps",
652
+ "graph",
653
+ "shield",
654
+ "users",
655
+ "chart-bar",
656
+ "search"
254
657
  ];
255
- var CustomIconTokenSchema = z.string().trim().max(80).regex(/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "Custom icon tokens must start with custom.");
658
+ var CustomIconTokenSchema = z.string().trim().max(80).regex(
659
+ /^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
660
+ 'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
661
+ );
256
662
  var OrganizationModelBuiltinIconTokenSchema = z.enum(ORGANIZATION_MODEL_ICON_TOKENS);
257
663
  var OrganizationModelIconTokenSchema = z.union([
258
664
  OrganizationModelBuiltinIconTokenSchema,
@@ -860,7 +1266,99 @@ var LEAD_GEN_ACTION_ENTRIES = Object.fromEntries(
860
1266
  return [parsed.id, parsed];
861
1267
  })
862
1268
  );
863
- var DEFAULT_ORGANIZATION_MODEL_ACTIONS = LEAD_GEN_ACTION_ENTRIES;
1269
+ var CRM_ACTION_ENTRY_INPUTS = [
1270
+ {
1271
+ id: "send_reply",
1272
+ order: 210,
1273
+ label: "Send Reply",
1274
+ description: "Send a contextual reply for an active CRM deal.",
1275
+ scope: { domain: "sales" },
1276
+ resourceId: "crm-send-reply-workflow",
1277
+ affects: ["crm.deal"]
1278
+ },
1279
+ {
1280
+ id: "send_link",
1281
+ order: 220,
1282
+ label: "Send Booking Link",
1283
+ description: "Send a booking link to move a deal toward a scheduled call.",
1284
+ scope: { domain: "sales" },
1285
+ resourceId: "crm-send-booking-link-workflow",
1286
+ affects: ["crm.deal"]
1287
+ },
1288
+ {
1289
+ id: "send_nudge",
1290
+ order: 230,
1291
+ label: "Send Nudge",
1292
+ description: "Send a follow-up nudge for a stalled CRM deal.",
1293
+ scope: { domain: "sales" },
1294
+ resourceId: "crm-send-nudge-workflow",
1295
+ affects: ["crm.deal"]
1296
+ },
1297
+ {
1298
+ id: "rebook",
1299
+ order: 240,
1300
+ label: "Rebook",
1301
+ description: "Rebook a missed or rescheduled CRM appointment.",
1302
+ scope: { domain: "sales" },
1303
+ resourceId: "crm-rebook-workflow",
1304
+ affects: ["crm.deal"]
1305
+ },
1306
+ {
1307
+ id: "move_to_proposal",
1308
+ order: 250,
1309
+ label: "Move to Proposal",
1310
+ description: "Advance a qualified CRM deal into the proposal stage.",
1311
+ scope: { domain: "sales" },
1312
+ resourceId: "move_to_proposal-workflow",
1313
+ affects: ["crm.deal"]
1314
+ },
1315
+ {
1316
+ id: "move_to_closing",
1317
+ order: 260,
1318
+ label: "Move to Closing",
1319
+ description: "Advance a proposal-stage CRM deal into closing.",
1320
+ scope: { domain: "sales" },
1321
+ resourceId: "move_to_closing-workflow",
1322
+ affects: ["crm.deal"]
1323
+ },
1324
+ {
1325
+ id: "move_to_closed_won",
1326
+ order: 270,
1327
+ label: "Close Won",
1328
+ description: "Mark a CRM deal as closed won.",
1329
+ scope: { domain: "sales" },
1330
+ resourceId: "move_to_closed_won-workflow",
1331
+ affects: ["crm.deal"]
1332
+ },
1333
+ {
1334
+ id: "move_to_closed_lost",
1335
+ order: 280,
1336
+ label: "Close Lost",
1337
+ description: "Mark a CRM deal as closed lost.",
1338
+ scope: { domain: "sales" },
1339
+ resourceId: "move_to_closed_lost-workflow",
1340
+ affects: ["crm.deal"]
1341
+ },
1342
+ {
1343
+ id: "move_to_nurturing",
1344
+ order: 290,
1345
+ label: "Move to Nurturing",
1346
+ description: "Move a CRM deal into nurturing for future follow-up.",
1347
+ scope: { domain: "sales" },
1348
+ resourceId: "move_to_nurturing-workflow",
1349
+ affects: ["crm.deal"]
1350
+ }
1351
+ ];
1352
+ var CRM_ACTION_ENTRIES = Object.fromEntries(
1353
+ CRM_ACTION_ENTRY_INPUTS.map((action) => {
1354
+ const parsed = ActionSchema.parse(action);
1355
+ return [parsed.id, parsed];
1356
+ })
1357
+ );
1358
+ var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {
1359
+ ...LEAD_GEN_ACTION_ENTRIES,
1360
+ ...CRM_ACTION_ENTRIES
1361
+ };
864
1362
  function findOrganizationActionById(id, actions = DEFAULT_ORGANIZATION_MODEL_ACTIONS) {
865
1363
  return actions[id];
866
1364
  }
@@ -886,6 +1384,17 @@ var SystemUiSchema = z.object({
886
1384
  icon: IconNameSchema.optional(),
887
1385
  order: z.number().int().optional()
888
1386
  });
1387
+ var JsonValueSchema = z.lazy(
1388
+ () => z.union([
1389
+ z.string(),
1390
+ z.number(),
1391
+ z.boolean(),
1392
+ z.null(),
1393
+ z.array(JsonValueSchema),
1394
+ z.record(z.string(), JsonValueSchema)
1395
+ ])
1396
+ );
1397
+ var SystemConfigSchema = z.record(z.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
889
1398
  var SystemEntrySchema = z.object({
890
1399
  /** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
891
1400
  id: SystemIdSchema,
@@ -931,11 +1440,21 @@ var SystemEntrySchema = z.object({
931
1440
  /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
932
1441
  order: z.number(),
933
1442
  /**
934
- * System-scoped operational data, co-located with the owning system.
935
- * Per L1, L3, L13: keyed by local NodeId (the key is the local id; qualified
936
- * id is `<system-path>:<local-id>`, computed by graph projection).
937
- * Per L14: every ContentNode carries both `kind` and `type`.
938
- * Per D2: unregistered (kind, type) pairs parse successfully.
1443
+ * System-local JSON settings and defaults. Strongly typed OM fields,
1444
+ * secrets, credentials, and runtime state stay outside this bucket.
1445
+ */
1446
+ config: SystemConfigSchema,
1447
+ /**
1448
+ * System-owned ontology declarations. `systems` is now the canonical child
1449
+ * key; this scope holds the object, action, catalog, link, event, and
1450
+ * shared contract records owned by this system.
1451
+ */
1452
+ ontology: OntologyScopeSchema.optional(),
1453
+ /**
1454
+ * @deprecated Compatibility-only bridge for old tenant content nodes and
1455
+ * migration readers. New schema/catalog authoring belongs in ontology;
1456
+ * new system-local settings belong in config. Bridge nodes are keyed by
1457
+ * local NodeId and may still project to content-node:* graph IDs.
939
1458
  */
940
1459
  content: z.record(z.string().trim().min(1).max(200), ContentNodeSchema).optional(),
941
1460
  /**
@@ -945,14 +1464,17 @@ var SystemEntrySchema = z.object({
945
1464
  * Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
946
1465
  * position-derived paths. Both still exist on this schema for backward compat.
947
1466
  */
1467
+ systems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
1468
+ /** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
948
1469
  subsystems: z.lazy(() => z.record(z.string().trim().min(1).max(100), SystemEntrySchema)).optional()
949
1470
  }).refine((system) => system.label !== void 0 || system.title !== void 0, {
950
1471
  path: ["label"],
951
1472
  message: "System must provide label or title"
952
1473
  }).transform((system) => {
953
- if (system.status === void 0) return system;
1474
+ const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
1475
+ if (normalizedSystem.status === void 0) return normalizedSystem;
954
1476
  console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
955
- return system.lifecycle === void 0 ? { ...system, lifecycle: system.status } : system;
1477
+ return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
956
1478
  });
957
1479
  var SystemsDomainSchema = z.record(z.string(), SystemEntrySchema).refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
958
1480
  message: "Each system entry id must match its map key"
@@ -964,6 +1486,7 @@ var ResourceKindSchema = z.enum(["workflow", "agent", "integration", "script"]).
964
1486
  var ResourceGovernanceStatusSchema = z.enum(["active", "deprecated", "archived"]).meta({ label: "Governance status", color: "teal" });
965
1487
  var AgentKindSchema = z.enum(["orchestrator", "specialist", "utility", "platform"]).meta({ label: "Agent kind", color: "violet" });
966
1488
  var ScriptResourceLanguageSchema = z.enum(["shell", "sql", "typescript", "python"]).meta({ label: "Language" });
1489
+ var CodeReferenceRoleSchema = z.enum(["entrypoint", "handler", "schema", "test", "docs", "config"]).meta({ label: "Code reference role", color: "blue" });
967
1490
  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");
968
1491
  var EventIdSchema = z.string().trim().min(1).max(300).regex(
969
1492
  /^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*:[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
@@ -981,6 +1504,28 @@ var EventDescriptorSchema = EventEmissionDescriptorSchema.extend({
981
1504
  ownerId: z.union([ResourceIdSchema, ModelIdSchema]),
982
1505
  ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
983
1506
  });
1507
+ var ResourceOntologyBindingSchema = z.object({
1508
+ actions: z.array(OntologyIdSchema).optional(),
1509
+ primaryAction: OntologyIdSchema.optional(),
1510
+ reads: z.array(OntologyIdSchema).optional(),
1511
+ writes: z.array(OntologyIdSchema).optional(),
1512
+ usesCatalogs: z.array(OntologyIdSchema).optional(),
1513
+ emits: z.array(OntologyIdSchema).optional()
1514
+ }).superRefine((binding, ctx) => {
1515
+ if (binding.primaryAction === void 0) return;
1516
+ if (binding.actions?.includes(binding.primaryAction)) return;
1517
+ ctx.addIssue({
1518
+ code: z.ZodIssueCode.custom,
1519
+ path: ["primaryAction"],
1520
+ message: "Resource ontology primaryAction must be included in actions"
1521
+ });
1522
+ });
1523
+ var CodeReferenceSchema = z.object({
1524
+ path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
1525
+ role: CodeReferenceRoleSchema,
1526
+ symbol: z.string().trim().min(1).max(200).optional(),
1527
+ description: z.string().trim().min(1).max(300).optional()
1528
+ });
984
1529
  var ResourceEntryBaseSchema = z.object({
985
1530
  /** Canonical resource id; runtime resourceId derives from this value. */
986
1531
  id: ResourceIdSchema,
@@ -988,14 +1533,24 @@ var ResourceEntryBaseSchema = z.object({
988
1533
  order: z.number().default(0),
989
1534
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
990
1535
  systemPath: SystemPathSchema.meta({ ref: "system" }),
1536
+ /** Executable display title owned by the OM Resource descriptor. */
1537
+ title: LabelSchema.optional(),
1538
+ /** Executable display description owned by the OM Resource descriptor. */
1539
+ description: DescriptionSchema.optional(),
991
1540
  /** Optional role responsible for maintaining this resource. */
992
1541
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
993
- status: ResourceGovernanceStatusSchema
1542
+ status: ResourceGovernanceStatusSchema,
1543
+ /**
1544
+ * Ontology contract bindings for the semantic work this resource performs.
1545
+ * `emits` stays nested here so top-level resource emits descriptors remain
1546
+ * compatible with graph event projection during the bridge.
1547
+ */
1548
+ ontology: ResourceOntologyBindingSchema.optional(),
1549
+ /** Repo-relative implementation breadcrumbs for agents and operators. */
1550
+ codeRefs: z.array(CodeReferenceSchema).default([])
994
1551
  });
995
1552
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
996
1553
  kind: z.literal("workflow"),
997
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
998
- actionKey: z.string().trim().min(1).max(255).optional(),
999
1554
  emits: z.array(EventEmissionDescriptorSchema).optional()
1000
1555
  });
1001
1556
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -1043,6 +1598,22 @@ function defineResources(resources) {
1043
1598
  Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
1044
1599
  );
1045
1600
  }
1601
+ function ontologyIdFrom(input) {
1602
+ return typeof input === "string" ? input : input.id;
1603
+ }
1604
+ function ontologyIdArrayFrom(input) {
1605
+ return input?.map(ontologyIdFrom);
1606
+ }
1607
+ function defineResourceOntology(input) {
1608
+ return ResourceOntologyBindingSchema.parse({
1609
+ actions: ontologyIdArrayFrom(input.actions),
1610
+ primaryAction: input.primaryAction === void 0 ? void 0 : ontologyIdFrom(input.primaryAction),
1611
+ reads: ontologyIdArrayFrom(input.reads),
1612
+ writes: ontologyIdArrayFrom(input.writes),
1613
+ usesCatalogs: ontologyIdArrayFrom(input.usesCatalogs),
1614
+ emits: ontologyIdArrayFrom(input.emits)
1615
+ });
1616
+ }
1046
1617
 
1047
1618
  // src/organization-model/domains/roles.ts
1048
1619
  var RoleIdSchema = ModelIdSchema;
@@ -1155,19 +1726,29 @@ var KnowledgeTargetKindSchema = z.enum([
1155
1726
  "goal",
1156
1727
  "customer-segment",
1157
1728
  "offering",
1729
+ "ontology",
1158
1730
  // D4: content nodes are a valid knowledge target after compound-domain data moved into system.content
1159
1731
  "content-node"
1160
1732
  ]).meta({ label: "Target kind" });
1161
1733
  var KnowledgeTargetRefSchema = z.object({
1162
1734
  kind: KnowledgeTargetKindSchema,
1163
- // D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'
1164
- // which contains a colon separator and cannot satisfy ModelIdSchema. Use a permissive
1165
- // string schema here; business-logic validation of target existence is done in
1166
- // OrganizationModelSchema.superRefine (knowledgeTargetExists).
1735
+ // D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'.
1736
+ // Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
1737
+ // Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
1167
1738
  id: z.string().trim().min(1).max(300)
1739
+ }).superRefine((target, ctx) => {
1740
+ if (target.kind !== "ontology") return;
1741
+ const result = OntologyIdSchema.safeParse(target.id);
1742
+ if (!result.success) {
1743
+ ctx.addIssue({
1744
+ code: z.ZodIssueCode.custom,
1745
+ path: ["id"],
1746
+ message: "Ontology knowledge targets must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
1747
+ });
1748
+ }
1168
1749
  });
1169
1750
  var LegacyKnowledgeLinkSchema = z.object({
1170
- nodeId: NodeIdStringSchema
1751
+ nodeId: z.union([NodeIdStringSchema, z.templateLiteral(["ontology:", OntologyIdSchema])])
1171
1752
  });
1172
1753
  var CanonicalKnowledgeLinkSchema = z.object({
1173
1754
  target: KnowledgeTargetRefSchema
@@ -1198,6 +1779,8 @@ var OrgKnowledgeNodeSchema = z.object({
1198
1779
  icon: IconNameSchema.optional(),
1199
1780
  /** Canonical documentation URL when body content is a local summary. */
1200
1781
  externalUrl: z.string().trim().url().max(500).optional(),
1782
+ /** Optional generated source file path for local MDX-backed knowledge nodes. */
1783
+ sourceFilePath: z.string().trim().min(1).max(500).optional(),
1201
1784
  /** Raw MDX string. Phase 2 will introduce a structured block format. */
1202
1785
  body: z.string().trim().min(1),
1203
1786
  /**
@@ -1211,6 +1794,179 @@ var OrgKnowledgeNodeSchema = z.object({
1211
1794
  updatedAt: z.string().trim().min(1).max(50)
1212
1795
  });
1213
1796
  var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
1797
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
1798
+ var SecretLikeMetadataValueSchema = /(?:sk-[A-Za-z0-9_-]{12,}|pk_live_[A-Za-z0-9_-]{12,}|eyJ[A-Za-z0-9_-]{20,}|-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----)/;
1799
+ var OmTopologyNodeKindSchema = z.enum([
1800
+ "system",
1801
+ "resource",
1802
+ "ontology",
1803
+ "policy",
1804
+ "role",
1805
+ "trigger",
1806
+ "humanCheckpoint",
1807
+ "externalResource"
1808
+ ]);
1809
+ var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
1810
+ var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
1811
+ z.object({ kind: z.literal("system"), id: ModelIdSchema }),
1812
+ z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
1813
+ z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
1814
+ z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
1815
+ z.object({ kind: z.literal("role"), id: ModelIdSchema }),
1816
+ z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
1817
+ z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
1818
+ z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
1819
+ ]);
1820
+ var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
1821
+ function visit(value, path) {
1822
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
1823
+ ctx.addIssue({
1824
+ code: z.ZodIssueCode.custom,
1825
+ path,
1826
+ message: "Topology metadata must not contain secret-like values"
1827
+ });
1828
+ return;
1829
+ }
1830
+ if (Array.isArray(value)) {
1831
+ value.forEach((entry, index) => visit(entry, [...path, index]));
1832
+ return;
1833
+ }
1834
+ if (typeof value !== "object" || value === null) return;
1835
+ Object.entries(value).forEach(([key, entry]) => {
1836
+ if (SecretLikeMetadataKeySchema.test(key)) {
1837
+ ctx.addIssue({
1838
+ code: z.ZodIssueCode.custom,
1839
+ path: [...path, key],
1840
+ message: `Topology metadata key "${key}" looks secret-like`
1841
+ });
1842
+ }
1843
+ visit(entry, [...path, key]);
1844
+ });
1845
+ }
1846
+ visit(metadata, []);
1847
+ });
1848
+ var OmTopologyRelationshipSchema = z.object({
1849
+ from: OmTopologyNodeRefSchema,
1850
+ kind: OmTopologyRelationshipKindSchema,
1851
+ to: OmTopologyNodeRefSchema,
1852
+ systemPath: SystemPathSchema.optional(),
1853
+ required: z.boolean().optional(),
1854
+ metadata: OmTopologyMetadataSchema.optional()
1855
+ });
1856
+ var OmTopologyDomainSchema = z.object({
1857
+ version: z.literal(1).default(1),
1858
+ relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
1859
+ }).default({ version: 1, relationships: {} });
1860
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
1861
+ version: 1,
1862
+ relationships: {}
1863
+ };
1864
+ function idFrom(input) {
1865
+ return typeof input === "string" ? input : input.id;
1866
+ }
1867
+ function parseRef(kind, id) {
1868
+ return OmTopologyNodeRefSchema.parse({ kind, id });
1869
+ }
1870
+ function isNodeRef(input) {
1871
+ return OmTopologyNodeRefSchema.safeParse(input).success;
1872
+ }
1873
+ function isResourceEntry(input) {
1874
+ if (typeof input !== "object" || input === null) return false;
1875
+ const candidate = input;
1876
+ return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
1877
+ }
1878
+ var topologyRef = {
1879
+ system: (system) => parseRef("system", idFrom(system)),
1880
+ resource: (resource) => parseRef("resource", idFrom(resource)),
1881
+ ontology: (record) => parseRef("ontology", idFrom(record)),
1882
+ policy: (policy) => parseRef("policy", idFrom(policy)),
1883
+ role: (role) => parseRef("role", idFrom(role)),
1884
+ trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
1885
+ humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
1886
+ externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
1887
+ };
1888
+ var topologyRelationship = {
1889
+ triggers: (from, to, options = {}) => defineTopologyRelationship({
1890
+ ...options,
1891
+ from,
1892
+ kind: "triggers",
1893
+ to
1894
+ }),
1895
+ uses: (from, to, options = {}) => defineTopologyRelationship({
1896
+ ...options,
1897
+ from,
1898
+ kind: "uses",
1899
+ to
1900
+ }),
1901
+ approval: (from, to, options = {}) => defineTopologyRelationship({
1902
+ ...options,
1903
+ from,
1904
+ kind: "approval",
1905
+ to
1906
+ }),
1907
+ usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
1908
+ required: true,
1909
+ ...options,
1910
+ from,
1911
+ kind: "uses",
1912
+ to: integration
1913
+ }),
1914
+ requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
1915
+ required: true,
1916
+ ...options,
1917
+ from,
1918
+ kind: "approval",
1919
+ to: topologyRef.humanCheckpoint(checkpoint)
1920
+ }),
1921
+ checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
1922
+ required: true,
1923
+ ...options,
1924
+ from: topologyRef.humanCheckpoint(checkpoint),
1925
+ kind: "triggers",
1926
+ to
1927
+ })
1928
+ };
1929
+ function compileTopologyNodeRef(input) {
1930
+ if (isNodeRef(input)) return input;
1931
+ if (isResourceEntry(input)) return topologyRef.resource(input);
1932
+ throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
1933
+ }
1934
+ function parseTopologyNodeRef(input) {
1935
+ if (typeof input !== "string") return OmTopologyNodeRefSchema.parse(input);
1936
+ const separatorIndex = input.indexOf(":");
1937
+ if (separatorIndex === -1) {
1938
+ throw new Error(`Topology node ref "${input}" must use <kind>:<id>`);
1939
+ }
1940
+ const kind = input.slice(0, separatorIndex);
1941
+ const id = input.slice(separatorIndex + 1);
1942
+ if (!OmTopologyNodeKindSchema.safeParse(kind).success) {
1943
+ throw new Error(`Topology node ref "${input}" has unsupported kind "${kind}"`);
1944
+ }
1945
+ return OmTopologyNodeRefSchema.parse({ kind, id });
1946
+ }
1947
+ function defineTopologyRelationship(input) {
1948
+ return OmTopologyRelationshipSchema.parse({
1949
+ ...input,
1950
+ from: compileTopologyNodeRef(input.from),
1951
+ to: compileTopologyNodeRef(input.to)
1952
+ });
1953
+ }
1954
+ function defineTopology(relationships) {
1955
+ const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
1956
+ return OmTopologyDomainSchema.parse({
1957
+ version: 1,
1958
+ relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
1959
+ });
1960
+ }
1961
+ function isOntologyTopologyRef(value) {
1962
+ if (!isNodeRef(value) || value.kind !== "ontology") return false;
1963
+ try {
1964
+ parseOntologyId(value.id);
1965
+ return true;
1966
+ } catch {
1967
+ return false;
1968
+ }
1969
+ }
1214
1970
  var PolicyIdSchema = ModelIdSchema;
1215
1971
  var PolicyApplicabilitySchema = z.object({
1216
1972
  systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
@@ -1298,7 +2054,9 @@ var OrganizationModelDomainKeySchema = z.enum([
1298
2054
  "roles",
1299
2055
  "goals",
1300
2056
  "systems",
2057
+ "ontology",
1301
2058
  "resources",
2059
+ "topology",
1302
2060
  "actions",
1303
2061
  "entities",
1304
2062
  "policies",
@@ -1316,7 +2074,9 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
1316
2074
  roles: { version: 1, lastModified: "2026-05-10" },
1317
2075
  goals: { version: 1, lastModified: "2026-05-10" },
1318
2076
  systems: { version: 1, lastModified: "2026-05-10" },
2077
+ ontology: { version: 1, lastModified: "2026-05-14" },
1319
2078
  resources: { version: 1, lastModified: "2026-05-10" },
2079
+ topology: { version: 1, lastModified: "2026-05-14" },
1320
2080
  actions: { version: 1, lastModified: "2026-05-10" },
1321
2081
  entities: { version: 1, lastModified: "2026-05-10" },
1322
2082
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -1330,7 +2090,9 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
1330
2090
  roles: OrganizationModelDomainMetadataSchema,
1331
2091
  goals: OrganizationModelDomainMetadataSchema,
1332
2092
  systems: OrganizationModelDomainMetadataSchema,
2093
+ ontology: OrganizationModelDomainMetadataSchema,
1333
2094
  resources: OrganizationModelDomainMetadataSchema,
2095
+ topology: OrganizationModelDomainMetadataSchema,
1334
2096
  actions: OrganizationModelDomainMetadataSchema,
1335
2097
  entities: OrganizationModelDomainMetadataSchema,
1336
2098
  policies: OrganizationModelDomainMetadataSchema,
@@ -1347,7 +2109,9 @@ var OrganizationModelSchemaBase = z.object({
1347
2109
  roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
1348
2110
  goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
1349
2111
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
2112
+ ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
1350
2113
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
2114
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
1351
2115
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
1352
2116
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
1353
2117
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -1374,13 +2138,16 @@ function asRoleHolderArray(heldBy) {
1374
2138
  function isKnowledgeKindCompatibleWithTarget(knowledgeKind, targetKind) {
1375
2139
  if (knowledgeKind === "reference") return true;
1376
2140
  if (knowledgeKind === "playbook") {
1377
- return ["system", "resource", "stage", "action"].includes(targetKind);
2141
+ return ["system", "resource", "stage", "action", "ontology"].includes(targetKind);
1378
2142
  }
1379
2143
  if (knowledgeKind === "strategy") {
1380
- return ["system", "goal", "offering", "customer-segment"].includes(targetKind);
2144
+ return ["system", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
1381
2145
  }
1382
2146
  return false;
1383
2147
  }
2148
+ function isRecord(value) {
2149
+ return typeof value === "object" && value !== null && !Array.isArray(value);
2150
+ }
1384
2151
  var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
1385
2152
  function collectAllSystems(systems, prefix = "", schemaPath = ["systems"]) {
1386
2153
  const result = [];
@@ -1388,8 +2155,11 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1388
2155
  const path = prefix ? `${prefix}.${key}` : key;
1389
2156
  const currentSchemaPath = [...schemaPath, key];
1390
2157
  result.push({ path, schemaPath: currentSchemaPath, system });
1391
- if (system.subsystems !== void 0) {
1392
- result.push(...collectAllSystems(system.subsystems, path, [...currentSchemaPath, "subsystems"]));
2158
+ const childSystems = system.systems ?? system.subsystems;
2159
+ if (childSystems !== void 0) {
2160
+ result.push(
2161
+ ...collectAllSystems(childSystems, path, [...currentSchemaPath, system.systems !== void 0 ? "systems" : "subsystems"])
2162
+ );
1393
2163
  }
1394
2164
  }
1395
2165
  return result;
@@ -1409,7 +2179,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1409
2179
  `System "${system.id}" references unknown parent "${system.parentSystemId}"`
1410
2180
  );
1411
2181
  }
1412
- const hasChildren = Object.keys(system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes("."));
2182
+ const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes("."));
1413
2183
  const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
1414
2184
  if (contributesRoutePath) {
1415
2185
  const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path);
@@ -1425,7 +2195,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1425
2195
  }
1426
2196
  }
1427
2197
  if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
1428
- const hasEnabledDescendant = Object.values(system.subsystems ?? {}).some(
2198
+ const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
1429
2199
  (candidate) => isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
1430
2200
  ) || allSystems.some(
1431
2201
  (candidate) => candidate.path.startsWith(`${path}.`) && !candidate.path.slice(path.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
@@ -1670,6 +2440,79 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1670
2440
  const stageIds = /* @__PURE__ */ new Set();
1671
2441
  const actionIds = new Set(Object.keys(model.actions));
1672
2442
  const offeringsById = new Map(Object.entries(model.offerings));
2443
+ const ontologyCompilation = compileOrganizationOntology(model);
2444
+ const ontologyIndexByKind = {
2445
+ object: ontologyCompilation.ontology.objectTypes,
2446
+ link: ontologyCompilation.ontology.linkTypes,
2447
+ action: ontologyCompilation.ontology.actionTypes,
2448
+ catalog: ontologyCompilation.ontology.catalogTypes,
2449
+ event: ontologyCompilation.ontology.eventTypes,
2450
+ interface: ontologyCompilation.ontology.interfaceTypes,
2451
+ "value-type": ontologyCompilation.ontology.valueTypes,
2452
+ property: ontologyCompilation.ontology.sharedProperties,
2453
+ group: ontologyCompilation.ontology.groups,
2454
+ surface: ontologyCompilation.ontology.surfaces
2455
+ };
2456
+ const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
2457
+ function topologyTargetExists(ref) {
2458
+ if (ref.kind === "system") return systemsById.has(ref.id);
2459
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
2460
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
2461
+ if (ref.kind === "policy") return policiesById.has(ref.id);
2462
+ if (ref.kind === "role") return rolesById.has(ref.id);
2463
+ return true;
2464
+ }
2465
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
2466
+ ["from", "to"].forEach((side) => {
2467
+ const ref = relationship[side];
2468
+ if (topologyTargetExists(ref)) return;
2469
+ addIssue(
2470
+ ctx,
2471
+ ["topology", "relationships", relationshipId, side],
2472
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
2473
+ );
2474
+ });
2475
+ });
2476
+ const ontologyReferenceKeyKinds = {
2477
+ valueType: "value-type",
2478
+ catalogType: "catalog",
2479
+ objectType: "object",
2480
+ eventType: "event",
2481
+ actionType: "action",
2482
+ linkType: "link",
2483
+ interfaceType: "interface",
2484
+ propertyType: "property",
2485
+ groupType: "group",
2486
+ surfaceType: "surface",
2487
+ stepCatalog: "catalog"
2488
+ };
2489
+ function validateKnownOntologyReferences(ownerId, value, path, seen = /* @__PURE__ */ new WeakSet()) {
2490
+ if (Array.isArray(value)) {
2491
+ value.forEach((entry, index) => validateKnownOntologyReferences(ownerId, entry, [...path, index], seen));
2492
+ return;
2493
+ }
2494
+ if (!isRecord(value)) return;
2495
+ if (seen.has(value)) return;
2496
+ seen.add(value);
2497
+ Object.entries(value).forEach(([key, entry]) => {
2498
+ const expectedKind = ontologyReferenceKeyKinds[key];
2499
+ if (expectedKind !== void 0) {
2500
+ if (typeof entry !== "string") {
2501
+ addIssue(ctx, [...path, key], `Ontology record "${ownerId}" ${key} must be an ontology ID string`);
2502
+ } else if (ontologyIndexByKind[expectedKind][entry] === void 0) {
2503
+ addIssue(
2504
+ ctx,
2505
+ [...path, key],
2506
+ `Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
2507
+ );
2508
+ }
2509
+ }
2510
+ validateKnownOntologyReferences(ownerId, entry, [...path, key], seen);
2511
+ });
2512
+ }
2513
+ for (const { id, record } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
2514
+ validateKnownOntologyReferences(id, record, record.origin.path);
2515
+ }
1673
2516
  Object.values(model.policies).forEach((policy) => {
1674
2517
  policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
1675
2518
  if (!systemsById.has(systemId)) {
@@ -1723,6 +2566,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1723
2566
  if (kind === "goal") return goalsById.has(id);
1724
2567
  if (kind === "customer-segment") return segmentsById.has(id);
1725
2568
  if (kind === "offering") return offeringsById.has(id);
2569
+ if (kind === "ontology") return ontologyIds.has(id);
1726
2570
  return false;
1727
2571
  }
1728
2572
  Object.entries(model.knowledge).forEach(([nodeId, node]) => {
@@ -1766,6 +2610,34 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1766
2610
  );
1767
2611
  }
1768
2612
  });
2613
+ function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
2614
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
2615
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
2616
+ if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
2617
+ addIssue(
2618
+ ctx,
2619
+ [
2620
+ "resources",
2621
+ resourceId,
2622
+ "ontology",
2623
+ bindingKey,
2624
+ ...Array.isArray(ids) ? [ontologyIndex] : []
2625
+ ],
2626
+ `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
2627
+ );
2628
+ }
2629
+ });
2630
+ }
2631
+ Object.values(model.resources).forEach((resource) => {
2632
+ const binding = resource.ontology;
2633
+ if (binding === void 0) return;
2634
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
2635
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
2636
+ validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
2637
+ validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
2638
+ validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
2639
+ validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
2640
+ });
1769
2641
  Object.values(model.roles).forEach((role) => {
1770
2642
  if (role.heldBy === void 0) return;
1771
2643
  asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
@@ -1800,11 +2672,13 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1800
2672
  });
1801
2673
  });
1802
2674
  function validateSystemContent(system, systemPath) {
2675
+ const childSystems = system.systems ?? system.subsystems;
2676
+ const childKey = system.systems !== void 0 ? "systems" : "subsystems";
1803
2677
  const content = system.content;
1804
2678
  if (content === void 0 || Object.keys(content).length === 0) {
1805
- if (system.subsystems !== void 0) {
1806
- Object.entries(system.subsystems).forEach(([childKey, child]) => {
1807
- validateSystemContent(child, [...systemPath, "subsystems", childKey]);
2679
+ if (childSystems !== void 0) {
2680
+ Object.entries(childSystems).forEach(([childLocalId, child]) => {
2681
+ validateSystemContent(child, [...systemPath, childKey, childLocalId]);
1808
2682
  });
1809
2683
  }
1810
2684
  return;
@@ -1860,15 +2734,18 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
1860
2734
  }
1861
2735
  }
1862
2736
  });
1863
- if (system.subsystems !== void 0) {
1864
- Object.entries(system.subsystems).forEach(([childKey, child]) => {
1865
- validateSystemContent(child, [...systemPath, "subsystems", childKey]);
2737
+ if (childSystems !== void 0) {
2738
+ Object.entries(childSystems).forEach(([childLocalId, child]) => {
2739
+ validateSystemContent(child, [...systemPath, childKey, childLocalId]);
1866
2740
  });
1867
2741
  }
1868
2742
  }
1869
2743
  Object.entries(model.systems).forEach(([systemKey, system]) => {
1870
2744
  validateSystemContent(system, ["systems", systemKey]);
1871
2745
  });
2746
+ for (const diagnostic of ontologyCompilation.diagnostics) {
2747
+ addIssue(ctx, diagnostic.path, diagnostic.message);
2748
+ }
1872
2749
  });
1873
2750
  var OrganizationGraphNodeKindSchema = z.enum([
1874
2751
  "organization",
@@ -1887,6 +2764,7 @@ var OrganizationGraphNodeKindSchema = z.enum([
1887
2764
  "surface",
1888
2765
  "navigation-group",
1889
2766
  // Phase 3 preview — Phase 4 populates via graph projection of system.content entries.
2767
+ "ontology",
1890
2768
  "content-node"
1891
2769
  ]);
1892
2770
  var OrganizationGraphEdgeKindSchema = z.enum([
@@ -1900,24 +2778,30 @@ var OrganizationGraphEdgeKindSchema = z.enum([
1900
2778
  "emits",
1901
2779
  "originates_from",
1902
2780
  "triggers",
2781
+ "approval",
1903
2782
  "applies_to",
1904
- "effects"
2783
+ "effects",
2784
+ "actions",
2785
+ "reads",
2786
+ "writes",
2787
+ "uses_catalog"
1905
2788
  ]);
1906
2789
  var OrganizationGraphNodeSchema = z.object({
1907
- id: z.string().trim().min(1).max(200),
2790
+ id: z.string().trim().min(1).max(400),
1908
2791
  kind: OrganizationGraphNodeKindSchema,
1909
2792
  label: LabelSchema,
1910
- sourceId: z.string().trim().min(1).max(255).optional(),
2793
+ sourceId: z.string().trim().min(1).max(400).optional(),
1911
2794
  description: DescriptionSchema.optional(),
1912
2795
  icon: IconNameSchema.optional(),
1913
2796
  enabled: z.boolean().optional(),
2797
+ ontologyKind: z.string().trim().min(1).max(80).optional(),
1914
2798
  resourceType: z.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint", "script"]).optional()
1915
2799
  });
1916
2800
  var OrganizationGraphEdgeSchema = z.object({
1917
- id: z.string().trim().min(1).max(250),
2801
+ id: z.string().trim().min(1).max(900),
1918
2802
  kind: OrganizationGraphEdgeKindSchema,
1919
- sourceId: z.string().trim().min(1).max(200),
1920
- targetId: z.string().trim().min(1).max(200),
2803
+ sourceId: z.string().trim().min(1).max(400),
2804
+ targetId: z.string().trim().min(1).max(400),
1921
2805
  label: z.string().trim().min(1).max(120).optional(),
1922
2806
  relationshipType: z.enum(["triggers", "uses", "approval"]).optional()
1923
2807
  });
@@ -1973,14 +2857,14 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
1973
2857
  label: "Dashboard",
1974
2858
  path: "/",
1975
2859
  surfaceType: "dashboard",
1976
- icon: "feature.dashboard",
2860
+ icon: "dashboard",
1977
2861
  order: 10,
1978
2862
  targets: { systems: ["dashboard"] }
1979
2863
  },
1980
2864
  business: {
1981
2865
  type: "group",
1982
2866
  label: "Business",
1983
- icon: "feature.business",
2867
+ icon: "business",
1984
2868
  order: 20,
1985
2869
  children: {
1986
2870
  sales: {
@@ -1988,7 +2872,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
1988
2872
  label: "Sales",
1989
2873
  path: "/sales",
1990
2874
  surfaceType: "page",
1991
- icon: "feature.sales",
2875
+ icon: "sales",
1992
2876
  order: 10,
1993
2877
  targets: { systems: ["sales"] }
1994
2878
  },
@@ -1997,7 +2881,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
1997
2881
  label: "Clients",
1998
2882
  path: "/clients",
1999
2883
  surfaceType: "list",
2000
- icon: "feature.projects",
2884
+ icon: "projects",
2001
2885
  order: 20,
2002
2886
  targets: { systems: ["clients"] }
2003
2887
  },
@@ -2006,7 +2890,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
2006
2890
  label: "Projects",
2007
2891
  path: "/projects",
2008
2892
  surfaceType: "page",
2009
- icon: "feature.projects",
2893
+ icon: "projects",
2010
2894
  order: 30,
2011
2895
  targets: { systems: ["projects"] }
2012
2896
  }
@@ -2015,7 +2899,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
2015
2899
  operations: {
2016
2900
  type: "group",
2017
2901
  label: "Operations",
2018
- icon: "feature.operations",
2902
+ icon: "operations",
2019
2903
  order: 30,
2020
2904
  children: {
2021
2905
  "operations-overview": {
@@ -2063,7 +2947,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
2063
2947
  monitoring: {
2064
2948
  type: "group",
2065
2949
  label: "Monitoring",
2066
- icon: "feature.monitoring",
2950
+ icon: "monitoring",
2067
2951
  order: 40,
2068
2952
  children: {
2069
2953
  "monitoring-overview": {
@@ -2125,36 +3009,19 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
2125
3009
  }
2126
3010
  },
2127
3011
  knowledge: {
2128
- type: "group",
2129
- label: "Knowledge",
2130
- icon: "feature.knowledge",
2131
- order: 50,
2132
- children: {
2133
- "knowledge-base": {
2134
- type: "surface",
2135
- label: "Knowledge Base",
2136
- path: "/knowledge",
2137
- surfaceType: "page",
2138
- order: 10,
2139
- targets: { systems: ["knowledge.base"] }
2140
- },
2141
- "knowledge-command-view": {
2142
- type: "surface",
2143
- label: "Command View",
2144
- path: "/knowledge/command-view",
2145
- surfaceType: "graph",
2146
- order: 20,
2147
- targets: { systems: ["knowledge.command-view"] },
2148
- devOnly: true
2149
- }
2150
- }
3012
+ type: "surface",
3013
+ label: "Knowledge Base",
3014
+ path: "/knowledge",
3015
+ surfaceType: "page",
3016
+ icon: "knowledge",
3017
+ order: 50
2151
3018
  }
2152
3019
  },
2153
3020
  bottom: {
2154
3021
  settings: {
2155
3022
  type: "group",
2156
3023
  label: "Settings",
2157
- icon: "feature.settings",
3024
+ icon: "settings",
2158
3025
  order: 10,
2159
3026
  children: {
2160
3027
  "settings-account": {
@@ -2226,7 +3093,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION2 = {
2226
3093
  admin: {
2227
3094
  type: "group",
2228
3095
  label: "Admin",
2229
- icon: "feature.admin",
3096
+ icon: "admin",
2230
3097
  order: 20,
2231
3098
  children: {
2232
3099
  "admin-dashboard": {
@@ -2306,7 +3173,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2306
3173
  enabled: true,
2307
3174
  lifecycle: "active",
2308
3175
  path: "/",
2309
- icon: "feature.dashboard"
3176
+ icon: "dashboard"
2310
3177
  },
2311
3178
  platform: {
2312
3179
  id: "platform",
@@ -2316,7 +3183,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2316
3183
  enabled: true,
2317
3184
  lifecycle: "active",
2318
3185
  color: "cyan",
2319
- icon: "feature.platform"
3186
+ icon: "platform"
2320
3187
  },
2321
3188
  finance: {
2322
3189
  id: "finance",
@@ -2326,7 +3193,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2326
3193
  enabled: true,
2327
3194
  lifecycle: "active",
2328
3195
  color: "green",
2329
- icon: "feature.finance"
3196
+ icon: "finance"
2330
3197
  },
2331
3198
  sales: {
2332
3199
  id: "sales",
@@ -2336,7 +3203,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2336
3203
  enabled: true,
2337
3204
  lifecycle: "active",
2338
3205
  color: "blue",
2339
- icon: "feature.sales",
3206
+ icon: "sales",
2340
3207
  path: "/sales"
2341
3208
  },
2342
3209
  "sales.crm": {
@@ -2346,8 +3213,12 @@ var DEFAULT_ORGANIZATION_MODEL = {
2346
3213
  description: "Relationship pipeline and deal management",
2347
3214
  enabled: true,
2348
3215
  lifecycle: "active",
3216
+ actions: Object.values(CRM_ACTION_ENTRIES).map((action) => ({
3217
+ actionId: action.id,
3218
+ intent: "exposes"
3219
+ })),
2349
3220
  color: "blue",
2350
- icon: "feature.crm",
3221
+ icon: "crm",
2351
3222
  path: "/crm"
2352
3223
  },
2353
3224
  "sales.lead-gen": {
@@ -2357,12 +3228,12 @@ var DEFAULT_ORGANIZATION_MODEL = {
2357
3228
  description: "Prospecting, qualification, and outreach preparation",
2358
3229
  enabled: true,
2359
3230
  lifecycle: "active",
2360
- actions: Object.values(DEFAULT_ORGANIZATION_MODEL_ACTIONS).map((action) => ({
3231
+ actions: Object.values(LEAD_GEN_ACTION_ENTRIES).map((action) => ({
2361
3232
  actionId: action.id,
2362
3233
  intent: "exposes"
2363
3234
  })),
2364
3235
  color: "cyan",
2365
- icon: "feature.lead-gen",
3236
+ icon: "lead-gen",
2366
3237
  path: "/lead-gen"
2367
3238
  },
2368
3239
  projects: {
@@ -2373,7 +3244,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2373
3244
  enabled: true,
2374
3245
  lifecycle: "active",
2375
3246
  color: "orange",
2376
- icon: "feature.projects",
3247
+ icon: "projects",
2377
3248
  path: "/projects"
2378
3249
  },
2379
3250
  clients: {
@@ -2384,7 +3255,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2384
3255
  enabled: true,
2385
3256
  lifecycle: "active",
2386
3257
  color: "orange",
2387
- icon: "feature.projects",
3258
+ icon: "projects",
2388
3259
  path: "/clients"
2389
3260
  },
2390
3261
  operations: {
@@ -2395,7 +3266,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2395
3266
  enabled: true,
2396
3267
  lifecycle: "active",
2397
3268
  color: "violet",
2398
- icon: "feature.operations"
3269
+ icon: "operations"
2399
3270
  },
2400
3271
  "knowledge.command-view": {
2401
3272
  id: "knowledge.command-view",
@@ -2461,7 +3332,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2461
3332
  enabled: true,
2462
3333
  lifecycle: "active",
2463
3334
  path: "/monitoring/calendar",
2464
- icon: "feature.calendar"
3335
+ icon: "calendar"
2465
3336
  },
2466
3337
  "monitoring.activity-log": {
2467
3338
  id: "monitoring.activity-log",
@@ -2517,7 +3388,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2517
3388
  label: "Settings",
2518
3389
  enabled: true,
2519
3390
  lifecycle: "active",
2520
- icon: "feature.settings"
3391
+ icon: "settings"
2521
3392
  },
2522
3393
  "settings.account": {
2523
3394
  id: "settings.account",
@@ -2590,7 +3461,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2590
3461
  enabled: true,
2591
3462
  lifecycle: "active",
2592
3463
  path: "/admin",
2593
- icon: "feature.admin",
3464
+ icon: "admin",
2594
3465
  requiresAdmin: true
2595
3466
  },
2596
3467
  "admin.system-health": {
@@ -2640,7 +3511,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2640
3511
  enabled: true,
2641
3512
  lifecycle: "active",
2642
3513
  path: "/archive",
2643
- icon: "feature.archive",
3514
+ icon: "archive",
2644
3515
  devOnly: true
2645
3516
  },
2646
3517
  "archive.agent-chat": {
@@ -2675,7 +3546,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
2675
3546
  enabled: true,
2676
3547
  lifecycle: "active",
2677
3548
  color: "teal",
2678
- icon: "feature.knowledge"
3549
+ icon: "knowledge"
2679
3550
  },
2680
3551
  "knowledge.base": {
2681
3552
  id: "knowledge.base",
@@ -2686,11 +3557,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
2686
3557
  path: "/knowledge"
2687
3558
  }
2688
3559
  },
3560
+ ontology: DEFAULT_ONTOLOGY_SCOPE,
2689
3561
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
3562
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
2690
3563
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
2691
3564
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
2692
3565
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
2693
- // Phase 4 (D1): statuses top-level field removed; status data lives in system.content.
3566
+ // Phase 4 (D1): statuses top-level field removed; bridge status mirrors may
3567
+ // still project from System.content, but primary authoring belongs in ontology.
2694
3568
  knowledge: DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE
2695
3569
  };
2696
3570
  var StatusSemanticClassSchema = z.enum([
@@ -3091,25 +3965,89 @@ var LEAD_GEN_STAGE_CATALOG = {
3091
3965
  };
3092
3966
 
3093
3967
  // src/organization-model/helpers.ts
3968
+ function childSystemsOf2(system) {
3969
+ return system.systems ?? system.subsystems ?? {};
3970
+ }
3971
+ function getSystem(model, path) {
3972
+ const segments = path.split(".");
3973
+ let current = model.systems;
3974
+ let node;
3975
+ for (const seg of segments) {
3976
+ node = current[seg];
3977
+ if (node === void 0) return void 0;
3978
+ current = childSystemsOf2(node);
3979
+ }
3980
+ return node;
3981
+ }
3094
3982
  function listAllSystems(model) {
3095
3983
  const results = [];
3096
3984
  function walk(map, prefix) {
3097
3985
  for (const [localId, system] of Object.entries(map)) {
3098
3986
  const fullPath = prefix ? `${prefix}.${localId}` : localId;
3099
3987
  results.push({ path: fullPath, system });
3100
- if (system.subsystems) {
3101
- walk(system.subsystems, fullPath);
3988
+ const childSystems = childSystemsOf2(system);
3989
+ if (Object.keys(childSystems).length > 0) {
3990
+ walk(childSystems, fullPath);
3102
3991
  }
3103
3992
  }
3104
3993
  }
3105
3994
  walk(model.systems, "");
3106
3995
  return results;
3107
3996
  }
3997
+ function isPlainJsonObject(value) {
3998
+ return typeof value === "object" && value !== null && !Array.isArray(value);
3999
+ }
4000
+ function mergeJsonConfig(base, override) {
4001
+ const result = { ...base };
4002
+ for (const [key, value] of Object.entries(override)) {
4003
+ const existing = result[key];
4004
+ result[key] = isPlainJsonObject(existing) && isPlainJsonObject(value) ? mergeJsonConfig(existing, value) : value;
4005
+ }
4006
+ return result;
4007
+ }
4008
+ function resolveSystemConfig(model, path) {
4009
+ const system = getSystem(model, path);
4010
+ if (system === void 0) return {};
4011
+ let resolved = {};
4012
+ for (const node of Object.values(system.content ?? {})) {
4013
+ if (node.kind !== "config" || node.type !== "kv") continue;
4014
+ const entries = node.data?.entries;
4015
+ if (isPlainJsonObject(entries)) {
4016
+ resolved = mergeJsonConfig(resolved, entries);
4017
+ }
4018
+ }
4019
+ return mergeJsonConfig(resolved, system.config ?? {});
4020
+ }
3108
4021
 
3109
4022
  // src/organization-model/resolve.ts
3110
4023
  function isPlainObject(value) {
3111
4024
  return typeof value === "object" && value !== null && !Array.isArray(value);
3112
4025
  }
4026
+ function collectNestedSystemPaths(systems, prefix = "") {
4027
+ const paths = /* @__PURE__ */ new Set();
4028
+ for (const [key, value] of Object.entries(systems)) {
4029
+ if (!isPlainObject(value)) continue;
4030
+ const path = prefix ? `${prefix}.${key}` : key;
4031
+ for (const childKey of ["systems", "subsystems"]) {
4032
+ const childSystems = value[childKey];
4033
+ if (!isPlainObject(childSystems)) continue;
4034
+ for (const childPath of collectNestedSystemPaths(childSystems, path)) {
4035
+ paths.add(childPath);
4036
+ }
4037
+ }
4038
+ if (prefix !== "") {
4039
+ paths.add(path);
4040
+ }
4041
+ }
4042
+ return paths;
4043
+ }
4044
+ function pruneFlatSystemDescendantCollisions(base, override) {
4045
+ const result = { ...base };
4046
+ for (const nestedPath of collectNestedSystemPaths(override)) {
4047
+ delete result[nestedPath];
4048
+ }
4049
+ return result;
4050
+ }
3113
4051
  function deepMerge(base, override) {
3114
4052
  if (override === void 0) {
3115
4053
  return base;
@@ -3124,6 +4062,10 @@ function deepMerge(base, override) {
3124
4062
  for (const [key, value] of Object.entries(override)) {
3125
4063
  if (value === void 0) continue;
3126
4064
  const existing = result[key];
4065
+ if (key === "systems" && isPlainObject(existing) && isPlainObject(value)) {
4066
+ result[key] = deepMerge(pruneFlatSystemDescendantCollisions(existing, value), value);
4067
+ continue;
4068
+ }
3127
4069
  result[key] = isPlainObject(existing) && isPlainObject(value) ? deepMerge(existing, value) : value;
3128
4070
  }
3129
4071
  return result;
@@ -3131,12 +4073,14 @@ function deepMerge(base, override) {
3131
4073
  function defineOrganizationModel(model) {
3132
4074
  return model;
3133
4075
  }
3134
- function resolveOrganizationModel(override, organizationId) {
3135
- const merged = deepMerge(DEFAULT_ORGANIZATION_MODEL, override);
4076
+ function resolveOrganizationModel(override, organizationIdOrOptions, options) {
4077
+ const resolvedOptions = typeof organizationIdOrOptions === "object" ? organizationIdOrOptions : options;
4078
+ const mergeDefaults = resolvedOptions?.mergeDefaults ?? true;
4079
+ const merged = mergeDefaults ? deepMerge(DEFAULT_ORGANIZATION_MODEL, override) : override ?? {};
3136
4080
  return OrganizationModelSchema.parse(merged);
3137
4081
  }
3138
4082
  function resolveOrganizationModelWithResources(override, organizationId) {
3139
- const model = resolveOrganizationModel(override);
4083
+ const model = resolveOrganizationModel(override, organizationId);
3140
4084
  const byPath = /* @__PURE__ */ new Map();
3141
4085
  for (const resource of Object.values(model.resources ?? {})) {
3142
4086
  const existing = byPath.get(resource.systemPath);
@@ -3149,7 +4093,8 @@ function resolveOrganizationModelWithResources(override, organizationId) {
3149
4093
  const enrichedSystems = {};
3150
4094
  for (const { path, system } of listAllSystems(model)) {
3151
4095
  const resources = byPath.get(path) ?? byPath.get(system.id);
3152
- enrichedSystems[path] = resources !== void 0 ? { ...system, id: path, resources } : { ...system, id: path };
4096
+ const config = resolveSystemConfig(model, path);
4097
+ enrichedSystems[path] = resources !== void 0 ? { ...system, id: path, config, resources } : { ...system, id: path, config };
3153
4098
  }
3154
4099
  return { ...model, systems: enrichedSystems };
3155
4100
  }
@@ -3263,4 +4208,4 @@ function createFoundationOrganizationModel(override) {
3263
4208
  };
3264
4209
  }
3265
4210
 
3266
- export { ActionIdSchema, ActionInvocationKindSchema, ActionInvocationSchema, ActionRefSchema, ActionSchema, ActionScopeSchema, ActionsDomainSchema, AgentKindSchema, AgentResourceEntrySchema, AgentRoleHolderSchema, ApiEndpointInvocationSchema, CustomerSegmentSchema, CustomersDomainSchema, DEFAULT_ORGANIZATION_MODEL, DEFAULT_ORGANIZATION_MODEL_ACTIONS, DEFAULT_ORGANIZATION_MODEL_CUSTOMERS, DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA, DEFAULT_ORGANIZATION_MODEL_ENTITIES, DEFAULT_ORGANIZATION_MODEL_GOALS, DEFAULT_ORGANIZATION_MODEL_NAVIGATION, DEFAULT_ORGANIZATION_MODEL_OFFERINGS, DEFAULT_ORGANIZATION_MODEL_POLICIES, DEFAULT_ORGANIZATION_MODEL_RESOURCES, DEFAULT_ORGANIZATION_MODEL_ROLES, DEFAULT_ORGANIZATION_MODEL_STATUSES, DEFAULT_ORGANIZATION_MODEL_SYSTEMS, EntitiesDomainSchema, EntityIdSchema, EntityLinkKindSchema, EntityLinkSchema, EntitySchema, EventDescriptorSchema, EventEmissionDescriptorSchema, EventIdSchema, FirmographicsSchema, GoalsDomainSchema, HumanRoleHolderSchema, IconNameSchema, IntegrationResourceEntrySchema, KNOWLEDGE_FEATURE_ID, KNOWLEDGE_SYSTEM_ID, KeyResultSchema, KnowledgeDomainSchema, KnowledgeLinkSchema, KnowledgeTargetKindSchema, KnowledgeTargetRefSchema, LEAD_GEN_ACTION_ENTRIES, LEAD_GEN_STAGE_CATALOG, LinkSchema, MONITORING_FEATURE_ID, MONITORING_SYSTEM_ID, McpToolInvocationSchema, NavigationGroupSchema, NodeIdPathSchema, NodeIdStringSchema, OPERATIONS_COMMAND_VIEW_SURFACE_ID, OPERATIONS_FEATURE_ID, OPERATIONS_SYSTEM_ID, ORGANIZATION_MODEL_ICON_TOKENS, ObjectiveSchema, OfferingsDomainSchema, OrgKnowledgeKindSchema, OrgKnowledgeNodeSchema, OrganizationModelBuiltinIconTokenSchema, OrganizationModelDomainKeySchema, OrganizationModelDomainMetadataByDomainSchema, OrganizationModelDomainMetadataSchema, OrganizationModelIconTokenSchema, OrganizationModelNavigationSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, PROJECTS_SYSTEM_ID, PROJECTS_VIEW_ACTION_ID, PROSPECTING_FEATURE_ID, PROSPECTING_LISTS_SURFACE_ID, PROSPECTING_SYSTEM_ID, PoliciesDomainSchema, PolicyApplicabilitySchema, PolicyEffectSchema, PolicyIdSchema, PolicyPredicateSchema, PolicySchema, PolicyTriggerSchema, PricingModelSchema, ProductSchema, ResourceEntrySchema, ResourceGovernanceStatusSchema, ResourceIdSchema, ResourceKindSchema, ResourcesDomainSchema, RoleHolderSchema, RoleHoldersSchema, RoleIdSchema, RoleSchema, RolesDomainSchema, SALES_FEATURE_ID, SALES_PIPELINE_SURFACE_ID, SALES_SYSTEM_ID, SEO_FEATURE_ID, SEO_SYSTEM_ID, SETTINGS_FEATURE_ID, SETTINGS_ROLES_SURFACE_ID, SETTINGS_SYSTEM_ID, ScriptExecutionInvocationSchema, ScriptResourceEntrySchema, ScriptResourceLanguageSchema, ScriptResourceSourceSchema, SidebarNavigationSchema, SidebarNodeSchema, SidebarSectionSchema, SidebarSurfaceTargetsSchema, SlashCommandInvocationSchema, StatusEntrySchema, StatusSemanticClassSchema, StatusesDomainSchema, SurfaceDefinitionSchema, SurfaceTypeSchema, SystemEntrySchema, SystemIdSchema, SystemKindSchema, SystemLifecycleSchema, SystemPathSchema, SystemStatusSchema, SystemUiSchema, SystemsDomainSchema, TeamRoleHolderSchema, TechStackEntrySchema, UiPositionSchema, WorkflowResourceEntrySchema, createFoundationOrganizationModel, defineOrganizationModel, defineResource, defineResources, findOrganizationActionById, getSortedSidebarEntries, resolveOrganizationModel, resolveOrganizationModelWithResources };
4211
+ export { ActionIdSchema, ActionInvocationKindSchema, ActionInvocationSchema, ActionRefSchema, ActionSchema, ActionScopeSchema, ActionsDomainSchema, AgentKindSchema, AgentResourceEntrySchema, AgentRoleHolderSchema, ApiEndpointInvocationSchema, CRM_ACTION_ENTRIES, CodeReferenceRoleSchema, CodeReferenceSchema, CustomerSegmentSchema, CustomersDomainSchema, DEFAULT_ONTOLOGY_SCOPE, DEFAULT_ORGANIZATION_MODEL, DEFAULT_ORGANIZATION_MODEL_ACTIONS, DEFAULT_ORGANIZATION_MODEL_CUSTOMERS, DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA, DEFAULT_ORGANIZATION_MODEL_ENTITIES, DEFAULT_ORGANIZATION_MODEL_GOALS, DEFAULT_ORGANIZATION_MODEL_NAVIGATION, DEFAULT_ORGANIZATION_MODEL_OFFERINGS, DEFAULT_ORGANIZATION_MODEL_POLICIES, DEFAULT_ORGANIZATION_MODEL_RESOURCES, DEFAULT_ORGANIZATION_MODEL_ROLES, DEFAULT_ORGANIZATION_MODEL_STATUSES, DEFAULT_ORGANIZATION_MODEL_SYSTEMS, DEFAULT_ORGANIZATION_MODEL_TOPOLOGY, EntitiesDomainSchema, EntityIdSchema, EntityLinkKindSchema, EntityLinkSchema, EntitySchema, EventDescriptorSchema, EventEmissionDescriptorSchema, EventIdSchema, FirmographicsSchema, GoalsDomainSchema, HumanRoleHolderSchema, IconNameSchema, IntegrationResourceEntrySchema, KNOWLEDGE_FEATURE_ID, KNOWLEDGE_SYSTEM_ID, KeyResultSchema, KnowledgeDomainSchema, KnowledgeLinkSchema, KnowledgeTargetKindSchema, KnowledgeTargetRefSchema, LEAD_GEN_ACTION_ENTRIES, LEAD_GEN_STAGE_CATALOG, LinkSchema, MONITORING_FEATURE_ID, MONITORING_SYSTEM_ID, McpToolInvocationSchema, NavigationGroupSchema, NodeIdPathSchema, NodeIdStringSchema, OPERATIONS_COMMAND_VIEW_SURFACE_ID, OPERATIONS_FEATURE_ID, OPERATIONS_SYSTEM_ID, ORGANIZATION_MODEL_ICON_TOKENS, ObjectiveSchema, OfferingsDomainSchema, OmTopologyDomainSchema, OmTopologyMetadataSchema, OmTopologyNodeKindSchema, OmTopologyNodeRefSchema, OmTopologyRelationshipKindSchema, OmTopologyRelationshipSchema, OntologyActionTypeSchema, OntologyCatalogTypeSchema, OntologyEventTypeSchema, OntologyGroupSchema, OntologyIdSchema, OntologyInterfaceTypeSchema, OntologyKindSchema, OntologyLinkTypeSchema, OntologyObjectTypeSchema, OntologyScopeSchema, OntologySharedPropertySchema, OntologySurfaceTypeSchema, OntologyValueTypeSchema, OrgKnowledgeKindSchema, OrgKnowledgeNodeSchema, OrganizationModelBuiltinIconTokenSchema, OrganizationModelDomainKeySchema, OrganizationModelDomainMetadataByDomainSchema, OrganizationModelDomainMetadataSchema, OrganizationModelIconTokenSchema, OrganizationModelNavigationSchema, OrganizationModelSchema, PROJECTS_FEATURE_ID, PROJECTS_INDEX_SURFACE_ID, PROJECTS_SYSTEM_ID, PROJECTS_VIEW_ACTION_ID, PROSPECTING_FEATURE_ID, PROSPECTING_LISTS_SURFACE_ID, PROSPECTING_SYSTEM_ID, PoliciesDomainSchema, PolicyApplicabilitySchema, PolicyEffectSchema, PolicyIdSchema, PolicyPredicateSchema, PolicySchema, PolicyTriggerSchema, PricingModelSchema, ProductSchema, ResourceEntrySchema, ResourceGovernanceStatusSchema, ResourceIdSchema, ResourceKindSchema, ResourceOntologyBindingSchema, ResourcesDomainSchema, RoleHolderSchema, RoleHoldersSchema, RoleIdSchema, RoleSchema, RolesDomainSchema, SALES_FEATURE_ID, SALES_PIPELINE_SURFACE_ID, SALES_SYSTEM_ID, SEO_FEATURE_ID, SEO_SYSTEM_ID, SETTINGS_FEATURE_ID, SETTINGS_ROLES_SURFACE_ID, SETTINGS_SYSTEM_ID, ScriptExecutionInvocationSchema, ScriptResourceEntrySchema, ScriptResourceLanguageSchema, ScriptResourceSourceSchema, SidebarNavigationSchema, SidebarNodeSchema, SidebarSectionSchema, SidebarSurfaceTargetsSchema, SlashCommandInvocationSchema, StatusEntrySchema, StatusSemanticClassSchema, StatusesDomainSchema, SurfaceDefinitionSchema, SurfaceTypeSchema, SystemEntrySchema, SystemIdSchema, SystemKindSchema, SystemLifecycleSchema, SystemPathSchema, SystemStatusSchema, SystemUiSchema, SystemsDomainSchema, TeamRoleHolderSchema, TechStackEntrySchema, UiPositionSchema, WorkflowResourceEntrySchema, compileOrganizationOntology, compileTopologyNodeRef, createFoundationOrganizationModel, defineOrganizationModel, defineResource, defineResourceOntology, defineResources, defineTopology, defineTopologyRelationship, findOrganizationActionById, formatOntologyId, getOntologyDiagnostics, getSortedSidebarEntries, isOntologyGraphNodeId, isOntologyTopologyRef, listResolvedOntologyRecords, ontologyGraphNodeId, ontologyIdFromGraphNodeId, parseOntologyId, parseTopologyNodeRef, resolveOrganizationModel, resolveOrganizationModelWithResources, topologyRef, topologyRelationship };