@elevasis/sdk 1.22.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/cli.cjs +980 -42
  2. package/dist/index.d.ts +1221 -220
  3. package/dist/index.js +390 -15
  4. package/dist/test-utils/index.d.ts +964 -211
  5. package/dist/test-utils/index.js +257 -14
  6. package/dist/worker/index.js +122 -14
  7. package/package.json +3 -3
  8. package/reference/claude-config/rules/operations.md +3 -3
  9. package/reference/claude-config/rules/organization-model.md +88 -85
  10. package/reference/claude-config/rules/organization-os.md +104 -104
  11. package/reference/claude-config/rules/vibe.md +235 -235
  12. package/reference/claude-config/skills/om/SKILL.md +324 -0
  13. package/reference/claude-config/skills/{knowledge → om}/operations/customers.md +110 -109
  14. package/reference/claude-config/skills/{knowledge → om}/operations/features.md +77 -76
  15. package/reference/claude-config/skills/{knowledge → om}/operations/goals.md +119 -118
  16. package/reference/claude-config/skills/{knowledge → om}/operations/identity.md +94 -93
  17. package/reference/claude-config/skills/{knowledge → om}/operations/labels.md +94 -94
  18. package/reference/claude-config/skills/{knowledge → om}/operations/offerings.md +110 -109
  19. package/reference/claude-config/skills/{knowledge → om}/operations/roles.md +100 -99
  20. package/reference/claude-config/skills/{knowledge → om}/operations/techStack.md +30 -30
  21. package/reference/claude-config/skills/project/SKILL.md +1088 -1088
  22. package/reference/claude-config/skills/setup/SKILL.md +275 -275
  23. package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
  24. package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
  25. package/reference/claude-config/skills/tutorial/technical.md +1303 -1303
  26. package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
  27. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +7 -4
  28. package/reference/claude-config/sync-notes/2026-05-15-om-skill-rename-and-write-family.md +52 -0
  29. package/reference/examples/organization-model.ts +26 -2
  30. package/reference/scaffold/core/organization-model.mdx +16 -11
  31. package/reference/scaffold/recipes/add-a-feature.md +28 -26
  32. package/reference/scaffold/recipes/add-a-resource.md +26 -16
  33. package/reference/scaffold/recipes/customize-organization-model.md +5 -3
  34. package/reference/scaffold/recipes/extend-lead-gen.md +9 -9
  35. package/reference/scaffold/recipes/index.md +1 -1
  36. package/reference/scaffold/recipes/query-the-knowledge-graph.md +189 -185
  37. package/reference/scaffold/reference/contracts.md +139 -101
  38. package/reference/scaffold/reference/glossary.md +74 -72
  39. package/reference/claude-config/skills/knowledge/SKILL.md +0 -345
  40. /package/reference/claude-config/skills/{knowledge → om}/operations/codify-level-a.md +0 -0
  41. /package/reference/claude-config/skills/{knowledge → om}/operations/codify-level-b.md +0 -0
package/dist/index.js CHANGED
@@ -68,6 +68,7 @@ var ORGANIZATION_MODEL_ICON_TOKENS = [
68
68
  "crm",
69
69
  "lead-gen",
70
70
  "projects",
71
+ "clients",
71
72
  "operations",
72
73
  "monitoring",
73
74
  "knowledge",
@@ -895,7 +896,6 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
895
896
  table: entity.table
896
897
  }
897
898
  } : {},
898
- legacyEntityId: entity.id,
899
899
  ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
900
900
  ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
901
901
  };
@@ -920,8 +920,7 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
920
920
  from: legacyObjectId(entity),
921
921
  to: legacyObjectId(targetEntity),
922
922
  cardinality: link.kind,
923
- ...link.via !== void 0 ? { via: link.via } : {},
924
- legacyEntityId: entity.id
923
+ ...link.via !== void 0 ? { via: link.via } : {}
925
924
  };
926
925
  addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
927
926
  source: "legacy.entities.links",
@@ -979,8 +978,7 @@ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath
979
978
  kind: node.type,
980
979
  ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
981
980
  ...Object.keys(entries).length > 0 ? { entries } : {},
982
- ...node.data !== void 0 ? { data: node.data } : {},
983
- legacyContentId: `${systemPath}:${localId}`
981
+ ...node.data !== void 0 ? { data: node.data } : {}
984
982
  };
985
983
  addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
986
984
  source: "legacy.system.content",
@@ -1535,11 +1533,20 @@ EventEmissionDescriptorSchema.extend({
1535
1533
  ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
1536
1534
  });
1537
1535
  var ResourceOntologyBindingSchema = z.object({
1538
- implements: z.array(OntologyIdSchema).optional(),
1536
+ actions: z.array(OntologyIdSchema).optional(),
1537
+ primaryAction: OntologyIdSchema.optional(),
1539
1538
  reads: z.array(OntologyIdSchema).optional(),
1540
1539
  writes: z.array(OntologyIdSchema).optional(),
1541
1540
  usesCatalogs: z.array(OntologyIdSchema).optional(),
1542
1541
  emits: z.array(OntologyIdSchema).optional()
1542
+ }).superRefine((binding, ctx) => {
1543
+ if (binding.primaryAction === void 0) return;
1544
+ if (binding.actions?.includes(binding.primaryAction)) return;
1545
+ ctx.addIssue({
1546
+ code: z.ZodIssueCode.custom,
1547
+ path: ["primaryAction"],
1548
+ message: "Resource ontology primaryAction must be included in actions"
1549
+ });
1543
1550
  });
1544
1551
  var CodeReferenceSchema = z.object({
1545
1552
  path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
@@ -1554,6 +1561,10 @@ var ResourceEntryBaseSchema = z.object({
1554
1561
  order: z.number().default(0),
1555
1562
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
1556
1563
  systemPath: SystemPathSchema.meta({ ref: "system" }),
1564
+ /** Executable display title owned by the OM Resource descriptor. */
1565
+ title: LabelSchema.optional(),
1566
+ /** Executable display description owned by the OM Resource descriptor. */
1567
+ description: DescriptionSchema.optional(),
1557
1568
  /** Optional role responsible for maintaining this resource. */
1558
1569
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
1559
1570
  status: ResourceGovernanceStatusSchema,
@@ -1568,8 +1579,6 @@ var ResourceEntryBaseSchema = z.object({
1568
1579
  });
1569
1580
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
1570
1581
  kind: z.literal("workflow"),
1571
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
1572
- actionKey: z.string().trim().min(1).max(255).optional(),
1573
1582
  emits: z.array(EventEmissionDescriptorSchema).optional()
1574
1583
  });
1575
1584
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -1609,6 +1618,30 @@ var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((re
1609
1618
  message: "Each resource entry id must match its map key"
1610
1619
  }).default({});
1611
1620
  var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
1621
+ function defineResource(resource) {
1622
+ return ResourceEntrySchema.parse(resource);
1623
+ }
1624
+ function defineResources(resources) {
1625
+ return Object.fromEntries(
1626
+ Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
1627
+ );
1628
+ }
1629
+ function ontologyIdFrom(input) {
1630
+ return typeof input === "string" ? input : input.id;
1631
+ }
1632
+ function ontologyIdArrayFrom(input) {
1633
+ return input?.map(ontologyIdFrom);
1634
+ }
1635
+ function defineResourceOntology(input) {
1636
+ return ResourceOntologyBindingSchema.parse({
1637
+ actions: ontologyIdArrayFrom(input.actions),
1638
+ primaryAction: input.primaryAction === void 0 ? void 0 : ontologyIdFrom(input.primaryAction),
1639
+ reads: ontologyIdArrayFrom(input.reads),
1640
+ writes: ontologyIdArrayFrom(input.writes),
1641
+ usesCatalogs: ontologyIdArrayFrom(input.usesCatalogs),
1642
+ emits: ontologyIdArrayFrom(input.emits)
1643
+ });
1644
+ }
1612
1645
 
1613
1646
  // ../core/src/organization-model/domains/roles.ts
1614
1647
  var RoleIdSchema = ModelIdSchema;
@@ -1789,6 +1822,170 @@ var OrgKnowledgeNodeSchema = z.object({
1789
1822
  updatedAt: z.string().trim().min(1).max(50)
1790
1823
  });
1791
1824
  var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
1825
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
1826
+ 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-----)/;
1827
+ var OmTopologyNodeKindSchema = z.enum([
1828
+ "system",
1829
+ "resource",
1830
+ "ontology",
1831
+ "policy",
1832
+ "role",
1833
+ "trigger",
1834
+ "humanCheckpoint",
1835
+ "externalResource"
1836
+ ]);
1837
+ var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
1838
+ var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
1839
+ z.object({ kind: z.literal("system"), id: ModelIdSchema }),
1840
+ z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
1841
+ z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
1842
+ z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
1843
+ z.object({ kind: z.literal("role"), id: ModelIdSchema }),
1844
+ z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
1845
+ z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
1846
+ z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
1847
+ ]);
1848
+ var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
1849
+ function visit(value, path) {
1850
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
1851
+ ctx.addIssue({
1852
+ code: z.ZodIssueCode.custom,
1853
+ path,
1854
+ message: "Topology metadata must not contain secret-like values"
1855
+ });
1856
+ return;
1857
+ }
1858
+ if (Array.isArray(value)) {
1859
+ value.forEach((entry, index) => visit(entry, [...path, index]));
1860
+ return;
1861
+ }
1862
+ if (typeof value !== "object" || value === null) return;
1863
+ Object.entries(value).forEach(([key, entry]) => {
1864
+ if (SecretLikeMetadataKeySchema.test(key)) {
1865
+ ctx.addIssue({
1866
+ code: z.ZodIssueCode.custom,
1867
+ path: [...path, key],
1868
+ message: `Topology metadata key "${key}" looks secret-like`
1869
+ });
1870
+ }
1871
+ visit(entry, [...path, key]);
1872
+ });
1873
+ }
1874
+ visit(metadata, []);
1875
+ });
1876
+ var OmTopologyRelationshipSchema = z.object({
1877
+ from: OmTopologyNodeRefSchema,
1878
+ kind: OmTopologyRelationshipKindSchema,
1879
+ to: OmTopologyNodeRefSchema,
1880
+ systemPath: SystemPathSchema.optional(),
1881
+ required: z.boolean().optional(),
1882
+ metadata: OmTopologyMetadataSchema.optional()
1883
+ });
1884
+ var OmTopologyDomainSchema = z.object({
1885
+ version: z.literal(1).default(1),
1886
+ relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
1887
+ }).default({ version: 1, relationships: {} });
1888
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
1889
+ version: 1,
1890
+ relationships: {}
1891
+ };
1892
+ function idFrom(input) {
1893
+ return typeof input === "string" ? input : input.id;
1894
+ }
1895
+ function parseRef(kind, id) {
1896
+ return OmTopologyNodeRefSchema.parse({ kind, id });
1897
+ }
1898
+ function isNodeRef(input) {
1899
+ return OmTopologyNodeRefSchema.safeParse(input).success;
1900
+ }
1901
+ function isResourceEntry(input) {
1902
+ if (typeof input !== "object" || input === null) return false;
1903
+ const candidate = input;
1904
+ return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
1905
+ }
1906
+ var topologyRef = {
1907
+ system: (system) => parseRef("system", idFrom(system)),
1908
+ resource: (resource) => parseRef("resource", idFrom(resource)),
1909
+ ontology: (record) => parseRef("ontology", idFrom(record)),
1910
+ policy: (policy) => parseRef("policy", idFrom(policy)),
1911
+ role: (role) => parseRef("role", idFrom(role)),
1912
+ trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
1913
+ humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
1914
+ externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
1915
+ };
1916
+ var topologyRelationship = {
1917
+ triggers: (from, to, options = {}) => defineTopologyRelationship({
1918
+ ...options,
1919
+ from,
1920
+ kind: "triggers",
1921
+ to
1922
+ }),
1923
+ uses: (from, to, options = {}) => defineTopologyRelationship({
1924
+ ...options,
1925
+ from,
1926
+ kind: "uses",
1927
+ to
1928
+ }),
1929
+ approval: (from, to, options = {}) => defineTopologyRelationship({
1930
+ ...options,
1931
+ from,
1932
+ kind: "approval",
1933
+ to
1934
+ }),
1935
+ usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
1936
+ required: true,
1937
+ ...options,
1938
+ from,
1939
+ kind: "uses",
1940
+ to: integration
1941
+ }),
1942
+ requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
1943
+ required: true,
1944
+ ...options,
1945
+ from,
1946
+ kind: "approval",
1947
+ to: topologyRef.humanCheckpoint(checkpoint)
1948
+ }),
1949
+ checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
1950
+ required: true,
1951
+ ...options,
1952
+ from: topologyRef.humanCheckpoint(checkpoint),
1953
+ kind: "triggers",
1954
+ to
1955
+ })
1956
+ };
1957
+ function compileTopologyNodeRef(input) {
1958
+ if (isNodeRef(input)) return input;
1959
+ if (isResourceEntry(input)) return topologyRef.resource(input);
1960
+ throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
1961
+ }
1962
+ function parseTopologyNodeRef(input) {
1963
+ if (typeof input !== "string") return OmTopologyNodeRefSchema.parse(input);
1964
+ const separatorIndex = input.indexOf(":");
1965
+ if (separatorIndex === -1) {
1966
+ throw new Error(`Topology node ref "${input}" must use <kind>:<id>`);
1967
+ }
1968
+ const kind = input.slice(0, separatorIndex);
1969
+ const id = input.slice(separatorIndex + 1);
1970
+ if (!OmTopologyNodeKindSchema.safeParse(kind).success) {
1971
+ throw new Error(`Topology node ref "${input}" has unsupported kind "${kind}"`);
1972
+ }
1973
+ return OmTopologyNodeRefSchema.parse({ kind, id });
1974
+ }
1975
+ function defineTopologyRelationship(input) {
1976
+ return OmTopologyRelationshipSchema.parse({
1977
+ ...input,
1978
+ from: compileTopologyNodeRef(input.from),
1979
+ to: compileTopologyNodeRef(input.to)
1980
+ });
1981
+ }
1982
+ function defineTopology(relationships) {
1983
+ const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
1984
+ return OmTopologyDomainSchema.parse({
1985
+ version: 1,
1986
+ relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
1987
+ });
1988
+ }
1792
1989
  var PolicyIdSchema = ModelIdSchema;
1793
1990
  var PolicyApplicabilitySchema = z.object({
1794
1991
  systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
@@ -1878,6 +2075,7 @@ z.enum([
1878
2075
  "systems",
1879
2076
  "ontology",
1880
2077
  "resources",
2078
+ "topology",
1881
2079
  "actions",
1882
2080
  "entities",
1883
2081
  "policies",
@@ -1897,6 +2095,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
1897
2095
  systems: { version: 1, lastModified: "2026-05-10" },
1898
2096
  ontology: { version: 1, lastModified: "2026-05-14" },
1899
2097
  resources: { version: 1, lastModified: "2026-05-10" },
2098
+ topology: { version: 1, lastModified: "2026-05-14" },
1900
2099
  actions: { version: 1, lastModified: "2026-05-10" },
1901
2100
  entities: { version: 1, lastModified: "2026-05-10" },
1902
2101
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -1912,6 +2111,7 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
1912
2111
  systems: OrganizationModelDomainMetadataSchema,
1913
2112
  ontology: OrganizationModelDomainMetadataSchema,
1914
2113
  resources: OrganizationModelDomainMetadataSchema,
2114
+ topology: OrganizationModelDomainMetadataSchema,
1915
2115
  actions: OrganizationModelDomainMetadataSchema,
1916
2116
  entities: OrganizationModelDomainMetadataSchema,
1917
2117
  policies: OrganizationModelDomainMetadataSchema,
@@ -1930,6 +2130,7 @@ var OrganizationModelSchemaBase = z.object({
1930
2130
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
1931
2131
  ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
1932
2132
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
2133
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
1933
2134
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
1934
2135
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
1935
2136
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -2272,6 +2473,25 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
2272
2473
  surface: ontologyCompilation.ontology.surfaces
2273
2474
  };
2274
2475
  const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
2476
+ function topologyTargetExists(ref) {
2477
+ if (ref.kind === "system") return systemsById.has(ref.id);
2478
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
2479
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
2480
+ if (ref.kind === "policy") return policiesById.has(ref.id);
2481
+ if (ref.kind === "role") return rolesById.has(ref.id);
2482
+ return true;
2483
+ }
2484
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
2485
+ ["from", "to"].forEach((side) => {
2486
+ const ref = relationship[side];
2487
+ if (topologyTargetExists(ref)) return;
2488
+ addIssue(
2489
+ ctx,
2490
+ ["topology", "relationships", relationshipId, side],
2491
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
2492
+ );
2493
+ });
2494
+ });
2275
2495
  const ontologyReferenceKeyKinds = {
2276
2496
  valueType: "value-type",
2277
2497
  catalogType: "catalog",
@@ -2410,11 +2630,18 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
2410
2630
  }
2411
2631
  });
2412
2632
  function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
2413
- ids?.forEach((ontologyId, ontologyIndex) => {
2633
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
2634
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
2414
2635
  if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
2415
2636
  addIssue(
2416
2637
  ctx,
2417
- ["resources", resourceId, "ontology", bindingKey, ontologyIndex],
2638
+ [
2639
+ "resources",
2640
+ resourceId,
2641
+ "ontology",
2642
+ bindingKey,
2643
+ ...Array.isArray(ids) ? [ontologyIndex] : []
2644
+ ],
2418
2645
  `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
2419
2646
  );
2420
2647
  }
@@ -2423,7 +2650,8 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
2423
2650
  Object.values(model.resources).forEach((resource) => {
2424
2651
  const binding = resource.ontology;
2425
2652
  if (binding === void 0) return;
2426
- validateResourceOntologyBinding(resource.id, "implements", "action", binding.implements);
2653
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
2654
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
2427
2655
  validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
2428
2656
  validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
2429
2657
  validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
@@ -2870,6 +3098,119 @@ function getRuntimeResources(resources) {
2870
3098
  }))
2871
3099
  ];
2872
3100
  }
3101
+ function hasOntologySources(organizationModel) {
3102
+ return organizationModel.ontology !== void 0 || organizationModel.entities !== void 0 || organizationModel.actions !== void 0 || Object.values(organizationModel.systems ?? {}).some(systemHasOntologySource);
3103
+ }
3104
+ function systemHasOntologySource(system) {
3105
+ if (system.ontology !== void 0 || system.content !== void 0 && Object.keys(system.content).length > 0) return true;
3106
+ return Object.values(system.systems ?? system.subsystems ?? {}).some(systemHasOntologySource);
3107
+ }
3108
+ function ontologyIndexForKind(index, kind) {
3109
+ switch (kind) {
3110
+ case "object":
3111
+ return index.objectTypes;
3112
+ case "link":
3113
+ return index.linkTypes;
3114
+ case "action":
3115
+ return index.actionTypes;
3116
+ case "catalog":
3117
+ return index.catalogTypes;
3118
+ case "event":
3119
+ return index.eventTypes;
3120
+ case "interface":
3121
+ return index.interfaceTypes;
3122
+ case "value-type":
3123
+ return index.valueTypes;
3124
+ case "property":
3125
+ return index.sharedProperties;
3126
+ case "group":
3127
+ return index.groups;
3128
+ case "surface":
3129
+ return index.surfaces;
3130
+ }
3131
+ }
3132
+ function sameJson(left, right) {
3133
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
3134
+ }
3135
+ function addOntologyBindingIssues(issues, orgName, resource, ontologyIndex) {
3136
+ const binding = resource.ontology;
3137
+ if (binding === void 0) return;
3138
+ if ((resource.kind === "workflow" || resource.kind === "agent") && (binding.actions?.length ?? 0) === 0) {
3139
+ addGovernanceIssue(
3140
+ issues,
3141
+ "missing-ontology-actions",
3142
+ orgName,
3143
+ resource.id,
3144
+ `[${orgName}] Resource '${resource.id}' declares ontology bindings but no ontology actions.`
3145
+ );
3146
+ }
3147
+ if (binding.primaryAction !== void 0 && !binding.actions?.includes(binding.primaryAction)) {
3148
+ addGovernanceIssue(
3149
+ issues,
3150
+ "primary-action-mismatch",
3151
+ orgName,
3152
+ resource.id,
3153
+ `[${orgName}] Resource '${resource.id}' primaryAction '${binding.primaryAction}' must be included in ontology.actions.`
3154
+ );
3155
+ }
3156
+ if (ontologyIndex === void 0) return;
3157
+ const validateRefs = (bindingKey, expectedKind, refs) => {
3158
+ const values = refs === void 0 ? [] : Array.isArray(refs) ? refs : [refs];
3159
+ const index = ontologyIndexForKind(ontologyIndex, expectedKind);
3160
+ for (const ref of values) {
3161
+ if (index[ref] !== void 0) continue;
3162
+ addGovernanceIssue(
3163
+ issues,
3164
+ "ontology-reference-missing",
3165
+ orgName,
3166
+ resource.id,
3167
+ `[${orgName}] Resource '${resource.id}' ontology.${bindingKey} references missing ${expectedKind} ontology record '${ref}'.`
3168
+ );
3169
+ }
3170
+ };
3171
+ validateRefs("actions", "action", binding.actions);
3172
+ validateRefs("primaryAction", "action", binding.primaryAction);
3173
+ validateRefs("reads", "object", binding.reads);
3174
+ validateRefs("writes", "object", binding.writes);
3175
+ validateRefs("usesCatalogs", "catalog", binding.usesCatalogs);
3176
+ validateRefs("emits", "event", binding.emits);
3177
+ }
3178
+ function addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex) {
3179
+ const relationships = organizationModel.topology?.relationships;
3180
+ if (relationships === void 0) return;
3181
+ const rolesById = new Set(Object.keys(organizationModel.roles ?? {}));
3182
+ const policiesById = new Set(Object.keys(organizationModel.policies ?? {}));
3183
+ const triggerIds = new Set(deployment.triggers?.map((trigger) => trigger.resourceId) ?? []);
3184
+ const humanCheckpointIds = new Set(deployment.humanCheckpoints?.map((checkpoint) => checkpoint.resourceId) ?? []);
3185
+ const externalResourceIds = new Set(deployment.externalResources?.map((external) => external.resourceId) ?? []);
3186
+ const topologyRefExists = (ref) => {
3187
+ if (ref.kind === "system") return systemsById.has(ref.id);
3188
+ if (ref.kind === "resource") return omResourcesById.has(ref.id);
3189
+ if (ref.kind === "policy") return policiesById.has(ref.id);
3190
+ if (ref.kind === "role") return rolesById.has(ref.id);
3191
+ if (ref.kind === "trigger") return triggerIds.has(ref.id);
3192
+ if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
3193
+ if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
3194
+ if (ref.kind === "ontology") {
3195
+ if (ontologyIndex === void 0) return true;
3196
+ return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
3197
+ }
3198
+ return false;
3199
+ };
3200
+ for (const [relationshipId, relationship] of Object.entries(relationships)) {
3201
+ ["from", "to"].forEach((side) => {
3202
+ const ref = relationship[side];
3203
+ if (topologyRefExists(ref)) return;
3204
+ addGovernanceIssue(
3205
+ issues,
3206
+ "topology-reference-missing",
3207
+ orgName,
3208
+ ref.id,
3209
+ `[${orgName}] Topology relationship '${relationshipId}' ${side} references missing ${ref.kind} '${ref.id}'.`
3210
+ );
3211
+ });
3212
+ }
3213
+ }
2873
3214
  function validateResourceGovernance(orgName, deployment, organizationModel = deployment.organizationModel, options = {}) {
2874
3215
  const mode = getResourceValidatorMode(options.mode);
2875
3216
  const omResourcesMap = organizationModel?.resources;
@@ -2885,6 +3226,17 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
2885
3226
  const omResourcesById = new Map(activeOmResources.map((resource) => [resource.id, resource]));
2886
3227
  const runtimeResources = getRuntimeResources(deployment);
2887
3228
  const runtimeResourcesById = new Map(runtimeResources.map((resource) => [resource.resourceId, resource]));
3229
+ const ontologyCompilation = hasOntologySources(organizationModel) ? compileOrganizationOntology(organizationModel) : void 0;
3230
+ const ontologyIndex = ontologyCompilation?.ontology;
3231
+ for (const diagnostic of ontologyCompilation?.diagnostics ?? []) {
3232
+ addGovernanceIssue(
3233
+ issues,
3234
+ "ontology-reference-missing",
3235
+ orgName,
3236
+ diagnostic.id,
3237
+ `[${orgName}] ${diagnostic.message}`
3238
+ );
3239
+ }
2888
3240
  for (const resource of activeOmResources) {
2889
3241
  if (!systemsById.has(resource.systemPath)) {
2890
3242
  addGovernanceIssue(
@@ -2924,6 +3276,16 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
2924
3276
  `[${orgName}] Resource '${resource.id}' system mismatch: code descriptor has '${runtimeResource.descriptor.systemPath}', OM has '${resource.systemPath}'.`
2925
3277
  );
2926
3278
  }
3279
+ if (runtimeResource.descriptor && !sameJson(runtimeResource.descriptor.ontology, resource.ontology)) {
3280
+ addGovernanceIssue(
3281
+ issues,
3282
+ "descriptor-mismatch",
3283
+ orgName,
3284
+ resource.id,
3285
+ `[${orgName}] Resource '${resource.id}' ontology descriptor mismatch between code and OM.`
3286
+ );
3287
+ }
3288
+ addOntologyBindingIssues(issues, orgName, resource, ontologyIndex);
2927
3289
  }
2928
3290
  for (const runtimeResource of runtimeResources) {
2929
3291
  const omResource = omResourcesById.get(runtimeResource.resourceId);
@@ -2965,6 +3327,7 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
2965
3327
  );
2966
3328
  }
2967
3329
  }
3330
+ addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex);
2968
3331
  emitGovernanceIssues(issues, mode, options.onWarning);
2969
3332
  return {
2970
3333
  valid: issues.length === 0,
@@ -6345,6 +6708,17 @@ var ResourceRegistry = class {
6345
6708
  return cache.commandView;
6346
6709
  }
6347
6710
  };
6711
+
6712
+ // ../core/src/platform/registry/types.ts
6713
+ function bindResourceDescriptor(definition) {
6714
+ const { resource, ...rest } = definition;
6715
+ return {
6716
+ ...rest,
6717
+ resource,
6718
+ resourceId: resource.id,
6719
+ type: resource.kind
6720
+ };
6721
+ }
6348
6722
  DisplayMetadataSchema.extend({
6349
6723
  id: ModelIdSchema,
6350
6724
  order: z.number().min(0)
@@ -6917,7 +7291,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
6917
7291
  business: {
6918
7292
  type: "group",
6919
7293
  label: "Business",
6920
- icon: "business",
7294
+ icon: "briefcase",
6921
7295
  order: 20,
6922
7296
  children: {
6923
7297
  sales: {
@@ -6934,7 +7308,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
6934
7308
  label: "Clients",
6935
7309
  path: "/clients",
6936
7310
  surfaceType: "list",
6937
- icon: "projects",
7311
+ icon: "clients",
6938
7312
  order: 20,
6939
7313
  targets: { systems: ["clients"] }
6940
7314
  },
@@ -7308,7 +7682,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
7308
7682
  enabled: true,
7309
7683
  lifecycle: "active",
7310
7684
  color: "orange",
7311
- icon: "projects",
7685
+ icon: "clients",
7312
7686
  path: "/clients"
7313
7687
  },
7314
7688
  operations: {
@@ -7612,6 +7986,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
7612
7986
  },
7613
7987
  ontology: DEFAULT_ONTOLOGY_SCOPE,
7614
7988
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
7989
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
7615
7990
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
7616
7991
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
7617
7992
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
@@ -8864,4 +9239,4 @@ function isOurReplyAction(deal) {
8864
9239
  var listBuilderStageKeys = Object.keys(LEAD_GEN_STAGE_CATALOG);
8865
9240
  var ListBuilderStageKeySchema = z.enum(listBuilderStageKeys);
8866
9241
 
8867
- export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, CRM_PIPELINE_DEFINITION, CrmStageKeySchema, CrmStateKeySchema, DEFAULT_CRM_ACTIONS, EmailSchema, ExecutionError, LEAD_GEN_STAGE_CATALOG, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, deriveActions, validateResourceGovernance };
9242
+ export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, CRM_PIPELINE_DEFINITION, CrmStageKeySchema, CrmStateKeySchema, DEFAULT_CRM_ACTIONS, EmailSchema, ExecutionError, LEAD_GEN_STAGE_CATALOG, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, bindResourceDescriptor, defineResource, defineResourceOntology, defineResources, defineTopology, defineTopologyRelationship, deriveActions, parseTopologyNodeRef, topologyRef, topologyRelationship, validateResourceGovernance };