@elevasis/sdk 1.21.0 → 1.22.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 (160) hide show
  1. package/dist/cli.cjs +1239 -173
  2. package/dist/index.d.ts +1752 -464
  3. package/dist/index.js +3477 -143
  4. package/dist/node/index.d.ts +1 -0
  5. package/dist/node/index.js +19 -1
  6. package/dist/test-utils/index.d.ts +1188 -127
  7. package/dist/test-utils/index.js +3359 -152
  8. package/dist/worker/index.js +3148 -80
  9. package/package.json +2 -2
  10. package/reference/claude-config/hooks/post-edit-validate.mjs +98 -98
  11. package/reference/claude-config/hooks/scaffold-registry-reminder.mjs +188 -188
  12. package/reference/claude-config/hooks/tool-failure-recovery.mjs +73 -73
  13. package/reference/claude-config/registries/graph-skills.json +4 -4
  14. package/reference/claude-config/registries/knowledge-flags.json +0 -2
  15. package/reference/claude-config/rules/active-change-index.md +80 -80
  16. package/reference/claude-config/rules/agent-start-here.md +277 -277
  17. package/reference/claude-config/rules/deployment.md +57 -57
  18. package/reference/claude-config/rules/error-handling.md +56 -56
  19. package/reference/claude-config/rules/execution.md +40 -40
  20. package/reference/claude-config/rules/frontend.md +4 -4
  21. package/reference/claude-config/rules/observability.md +31 -31
  22. package/reference/claude-config/rules/operations.md +29 -17
  23. package/reference/claude-config/rules/organization-model.md +113 -81
  24. package/reference/claude-config/rules/organization-os.md +115 -113
  25. package/reference/claude-config/rules/package-taxonomy.md +33 -33
  26. package/reference/claude-config/rules/platform.md +42 -42
  27. package/reference/claude-config/rules/shared-types.md +49 -46
  28. package/reference/claude-config/rules/task-tracking.md +47 -47
  29. package/reference/claude-config/rules/ui.md +200 -200
  30. package/reference/claude-config/rules/vibe.md +235 -235
  31. package/reference/claude-config/scripts/statusline-command.js +18 -18
  32. package/reference/claude-config/settings.json +34 -34
  33. package/reference/claude-config/skills/deploy/{SKILL.md → skill.md} +156 -156
  34. package/reference/claude-config/skills/dsp/SKILL.md +66 -66
  35. package/reference/claude-config/skills/elevasis/SKILL.md +235 -235
  36. package/reference/claude-config/skills/explore/SKILL.md +6 -6
  37. package/reference/claude-config/skills/git-sync/SKILL.md +126 -126
  38. package/reference/claude-config/skills/knowledge/SKILL.md +314 -299
  39. package/reference/claude-config/skills/knowledge/operations/codify-level-a.md +100 -100
  40. package/reference/claude-config/skills/knowledge/operations/codify-level-b.md +159 -159
  41. package/reference/claude-config/skills/knowledge/operations/customers.md +109 -109
  42. package/reference/claude-config/skills/knowledge/operations/features.md +76 -76
  43. package/reference/claude-config/skills/knowledge/operations/goals.md +118 -118
  44. package/reference/claude-config/skills/knowledge/operations/identity.md +93 -93
  45. package/reference/claude-config/skills/knowledge/operations/labels.md +94 -94
  46. package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -109
  47. package/reference/claude-config/skills/knowledge/operations/roles.md +99 -99
  48. package/reference/claude-config/skills/knowledge/operations/techStack.md +30 -30
  49. package/reference/claude-config/skills/project/SKILL.md +1088 -1088
  50. package/reference/claude-config/skills/run-ui/SKILL.md +73 -73
  51. package/reference/claude-config/skills/save/SKILL.md +3 -3
  52. package/reference/claude-config/skills/setup/SKILL.md +275 -275
  53. package/reference/claude-config/skills/status/SKILL.md +59 -59
  54. package/reference/claude-config/skills/submit-request/SKILL.md +180 -180
  55. package/reference/claude-config/skills/sync/SKILL.md +47 -47
  56. package/reference/claude-config/skills/tutorial/SKILL.md +259 -259
  57. package/reference/claude-config/skills/tutorial/progress-template.md +74 -74
  58. package/reference/claude-config/skills/tutorial/technical.md +1303 -1303
  59. package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -890
  60. package/reference/claude-config/sync-notes/2026-04-22-git-sync-and-sync-notes.md +27 -27
  61. package/reference/claude-config/sync-notes/2026-04-22-lead-gen-deliverability-removal.md +30 -30
  62. package/reference/claude-config/sync-notes/2026-04-24-test-utils-and-template-tests.md +73 -73
  63. package/reference/claude-config/sync-notes/2026-04-24-ui-consolidation-and-sdk-cli-train.md +86 -86
  64. package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -55
  65. package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +97 -97
  66. package/reference/claude-config/sync-notes/2026-04-27-lead-gen-substrate-train.md +112 -112
  67. package/reference/claude-config/sync-notes/2026-04-29-crm-state-and-lead-gen-processing-status.md +93 -93
  68. package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -58
  69. package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -56
  70. package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -71
  71. package/reference/claude-config/sync-notes/2026-05-04-knowledge-bundle.md +83 -83
  72. package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -59
  73. package/reference/claude-config/sync-notes/2026-05-05-list-builder.md +42 -42
  74. package/reference/claude-config/sync-notes/2026-05-06-crm-spine.md +60 -60
  75. package/reference/claude-config/sync-notes/2026-05-06-sdk-changes-release-train.md +37 -37
  76. package/reference/claude-config/sync-notes/2026-05-07-sdk-changes-release-train.md +34 -34
  77. package/reference/claude-config/sync-notes/2026-05-08-resource-governance-scaffold-guidance.md +38 -38
  78. package/reference/claude-config/sync-notes/2026-05-09-clients-domain.md +32 -32
  79. package/reference/claude-config/sync-notes/2026-05-09-command-system.md +33 -33
  80. package/reference/claude-config/sync-notes/2026-05-09-resource-governance-and-misc.md +69 -69
  81. package/reference/claude-config/sync-notes/2026-05-12-sdk-ready-release-train.md +30 -30
  82. package/reference/claude-config/sync-notes/2026-05-14-organization-model-ontology-refactor.md +45 -0
  83. package/reference/claude-config/sync-notes/README.md +43 -43
  84. package/reference/cli.mdx +808 -808
  85. package/reference/concepts.mdx +146 -146
  86. package/reference/deployment/api.mdx +297 -297
  87. package/reference/deployment/command-center.mdx +209 -209
  88. package/reference/deployment/index.mdx +195 -195
  89. package/reference/deployment/provided-features.mdx +107 -107
  90. package/reference/deployment/ui-execution.mdx +250 -250
  91. package/reference/examples/organization-model.ts +171 -84
  92. package/reference/framework/agent.mdx +156 -156
  93. package/reference/framework/index.mdx +195 -195
  94. package/reference/framework/interaction-guidance.mdx +182 -182
  95. package/reference/framework/memory.mdx +326 -326
  96. package/reference/framework/project-structure.mdx +282 -282
  97. package/reference/framework/tutorial-system.mdx +135 -135
  98. package/reference/getting-started.mdx +142 -142
  99. package/reference/index.mdx +106 -106
  100. package/reference/packages/core/src/README.md +14 -14
  101. package/reference/packages/core/src/business/README.md +2 -2
  102. package/reference/packages/core/src/knowledge/README.md +32 -32
  103. package/reference/packages/core/src/organization-model/README.md +149 -149
  104. package/reference/packages/core/src/test-utils/README.md +37 -37
  105. package/reference/packages/ui/src/api/README.md +18 -18
  106. package/reference/packages/ui/src/app/README.md +24 -24
  107. package/reference/packages/ui/src/auth/README.md +18 -18
  108. package/reference/packages/ui/src/components/README.md +24 -24
  109. package/reference/packages/ui/src/execution/README.md +16 -16
  110. package/reference/packages/ui/src/features/README.md +28 -28
  111. package/reference/packages/ui/src/graph/README.md +16 -16
  112. package/reference/packages/ui/src/hooks/README.md +23 -23
  113. package/reference/packages/ui/src/initialization/README.md +19 -19
  114. package/reference/packages/ui/src/knowledge/README.md +31 -31
  115. package/reference/packages/ui/src/organization/README.md +18 -18
  116. package/reference/packages/ui/src/profile/README.md +19 -19
  117. package/reference/packages/ui/src/provider/README.md +32 -32
  118. package/reference/packages/ui/src/router/README.md +18 -18
  119. package/reference/packages/ui/src/sse/README.md +13 -13
  120. package/reference/packages/ui/src/test-utils/README.md +7 -7
  121. package/reference/packages/ui/src/theme/README.md +23 -23
  122. package/reference/packages/ui/src/theme/presets/README.md +19 -19
  123. package/reference/packages/ui/src/types/README.md +16 -16
  124. package/reference/packages/ui/src/utils/README.md +18 -18
  125. package/reference/packages/ui/src/zustand/README.md +18 -18
  126. package/reference/platform-tools/adapters-integration.mdx +301 -301
  127. package/reference/platform-tools/adapters-platform.mdx +553 -553
  128. package/reference/platform-tools/index.mdx +217 -217
  129. package/reference/platform-tools/type-safety.mdx +82 -82
  130. package/reference/resources/index.mdx +349 -349
  131. package/reference/resources/patterns.mdx +449 -449
  132. package/reference/resources/types.mdx +116 -116
  133. package/reference/roadmap.mdx +165 -165
  134. package/reference/runtime.mdx +173 -173
  135. package/reference/scaffold/core/organization-graph.mdx +110 -90
  136. package/reference/scaffold/core/organization-model.mdx +225 -213
  137. package/reference/scaffold/index.mdx +67 -67
  138. package/reference/scaffold/operations/propagation-pipeline.md +77 -77
  139. package/reference/scaffold/operations/scaffold-maintenance.md +12 -12
  140. package/reference/scaffold/operations/workflow-recipes.md +138 -138
  141. package/reference/scaffold/recipes/add-a-feature.md +307 -85
  142. package/reference/scaffold/recipes/add-a-resource.md +137 -103
  143. package/reference/scaffold/recipes/customize-knowledge-browser.md +5 -5
  144. package/reference/scaffold/recipes/customize-organization-model.md +275 -138
  145. package/reference/scaffold/recipes/extend-a-base-entity.md +8 -8
  146. package/reference/scaffold/recipes/extend-crm.md +3 -3
  147. package/reference/scaffold/recipes/extend-lead-gen.md +394 -394
  148. package/reference/scaffold/recipes/gate-by-feature-or-admin.md +118 -118
  149. package/reference/scaffold/recipes/index.md +46 -46
  150. package/reference/scaffold/recipes/query-the-knowledge-graph.md +197 -170
  151. package/reference/scaffold/reference/contracts.md +2136 -2093
  152. package/reference/scaffold/reference/glossary.md +76 -76
  153. package/reference/scaffold/ui/composition-extensibility.mdx +233 -233
  154. package/reference/scaffold/ui/customization.md +243 -243
  155. package/reference/scaffold/ui/feature-flags-and-gating.md +46 -46
  156. package/reference/scaffold/ui/feature-shell.mdx +72 -72
  157. package/reference/scaffold/ui/recipes.md +221 -214
  158. package/reference/spine/spine-primer.md +96 -96
  159. package/reference/templates/index.mdx +47 -47
  160. package/reference/troubleshooting.mdx +223 -223
package/dist/cli.cjs CHANGED
@@ -36613,73 +36613,78 @@ var DateRangeSchema = external_exports.object({
36613
36613
 
36614
36614
  // ../core/src/organization-model/icons.ts
36615
36615
  var ORGANIZATION_MODEL_ICON_TOKENS = [
36616
- "nav.dashboard",
36617
- "nav.calendar",
36618
- "nav.sales",
36619
- "nav.crm",
36620
- "nav.lead-gen",
36621
- "nav.projects",
36622
- "nav.operations",
36623
- "nav.monitoring",
36624
- "nav.knowledge",
36625
- "nav.settings",
36626
- "nav.admin",
36627
- "nav.archive",
36628
- "knowledge.playbook",
36629
- "knowledge.strategy",
36630
- "knowledge.reference",
36631
- "feature.dashboard",
36632
- "feature.calendar",
36633
- "feature.business",
36634
- "feature.sales",
36635
- "feature.crm",
36636
- "feature.finance",
36637
- "feature.lead-gen",
36638
- "feature.platform",
36639
- "feature.projects",
36640
- "feature.operations",
36641
- "feature.knowledge",
36642
- "feature.monitoring",
36643
- "feature.settings",
36644
- "feature.admin",
36645
- "feature.archive",
36646
- "feature.seo",
36647
- "resource.agent",
36648
- "resource.workflow",
36649
- "resource.integration",
36650
- "resource.database",
36651
- "resource.user",
36652
- "resource.team",
36653
- "integration.gmail",
36654
- "integration.google-sheets",
36655
- "integration.attio",
36656
- "surface.dashboard",
36657
- "surface.calendar",
36658
- "surface.overview",
36659
- "surface.command-view",
36660
- "surface.command-queue",
36661
- "surface.pipeline",
36662
- "surface.lists",
36663
- "surface.resources",
36664
- "surface.settings",
36665
- "status.success",
36666
- "status.error",
36667
- "status.warning",
36668
- "status.info",
36669
- "status.pending",
36670
- "action.approve",
36671
- "action.reject",
36672
- "action.retry",
36673
- "action.edit",
36674
- "action.view",
36675
- "action.launch",
36676
- "action.message",
36677
- "action.escalate",
36678
- "action.promote",
36679
- "action.submit",
36680
- "action.email"
36616
+ // Navigation / app areas
36617
+ "dashboard",
36618
+ "calendar",
36619
+ "sales",
36620
+ "crm",
36621
+ "lead-gen",
36622
+ "projects",
36623
+ "operations",
36624
+ "monitoring",
36625
+ "knowledge",
36626
+ "settings",
36627
+ "admin",
36628
+ "archive",
36629
+ "business",
36630
+ "finance",
36631
+ "platform",
36632
+ "seo",
36633
+ // Knowledge kinds
36634
+ "playbook",
36635
+ "strategy",
36636
+ "reference",
36637
+ // Resource kinds
36638
+ "agent",
36639
+ "workflow",
36640
+ "integration",
36641
+ "database",
36642
+ "user",
36643
+ "team",
36644
+ // Integration specifics
36645
+ "gmail",
36646
+ "google-sheets",
36647
+ "attio",
36648
+ // Surface / UI views
36649
+ "overview",
36650
+ "command-view",
36651
+ "command-queue",
36652
+ "pipeline",
36653
+ "lists",
36654
+ "resources",
36655
+ // Actions
36656
+ "approve",
36657
+ "reject",
36658
+ "retry",
36659
+ "edit",
36660
+ "view",
36661
+ "launch",
36662
+ "message",
36663
+ "escalate",
36664
+ "promote",
36665
+ "submit",
36666
+ "email",
36667
+ // Status
36668
+ "success",
36669
+ "error",
36670
+ "warning",
36671
+ "info",
36672
+ "pending",
36673
+ // OM / UI group icons
36674
+ "bolt",
36675
+ "building",
36676
+ "briefcase",
36677
+ "apps",
36678
+ "graph",
36679
+ "shield",
36680
+ "users",
36681
+ "chart-bar",
36682
+ "search"
36681
36683
  ];
36682
- var CustomIconTokenSchema = external_exports.string().trim().max(80).regex(/^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/, "Custom icon tokens must start with custom.");
36684
+ var CustomIconTokenSchema = external_exports.string().trim().max(80).regex(
36685
+ /^custom\.[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
36686
+ 'Custom icon tokens must start with "custom." followed by lowercase alphanumeric segments'
36687
+ );
36683
36688
  var OrganizationModelBuiltinIconTokenSchema = external_exports.enum(ORGANIZATION_MODEL_ICON_TOKENS);
36684
36689
  var OrganizationModelIconTokenSchema = external_exports.union([
36685
36690
  OrganizationModelBuiltinIconTokenSchema,
@@ -37041,7 +37046,99 @@ var LEAD_GEN_ACTION_ENTRIES = Object.fromEntries(
37041
37046
  return [parsed.id, parsed];
37042
37047
  })
37043
37048
  );
37044
- var DEFAULT_ORGANIZATION_MODEL_ACTIONS = LEAD_GEN_ACTION_ENTRIES;
37049
+ var CRM_ACTION_ENTRY_INPUTS = [
37050
+ {
37051
+ id: "send_reply",
37052
+ order: 210,
37053
+ label: "Send Reply",
37054
+ description: "Send a contextual reply for an active CRM deal.",
37055
+ scope: { domain: "sales" },
37056
+ resourceId: "crm-send-reply-workflow",
37057
+ affects: ["crm.deal"]
37058
+ },
37059
+ {
37060
+ id: "send_link",
37061
+ order: 220,
37062
+ label: "Send Booking Link",
37063
+ description: "Send a booking link to move a deal toward a scheduled call.",
37064
+ scope: { domain: "sales" },
37065
+ resourceId: "crm-send-booking-link-workflow",
37066
+ affects: ["crm.deal"]
37067
+ },
37068
+ {
37069
+ id: "send_nudge",
37070
+ order: 230,
37071
+ label: "Send Nudge",
37072
+ description: "Send a follow-up nudge for a stalled CRM deal.",
37073
+ scope: { domain: "sales" },
37074
+ resourceId: "crm-send-nudge-workflow",
37075
+ affects: ["crm.deal"]
37076
+ },
37077
+ {
37078
+ id: "rebook",
37079
+ order: 240,
37080
+ label: "Rebook",
37081
+ description: "Rebook a missed or rescheduled CRM appointment.",
37082
+ scope: { domain: "sales" },
37083
+ resourceId: "crm-rebook-workflow",
37084
+ affects: ["crm.deal"]
37085
+ },
37086
+ {
37087
+ id: "move_to_proposal",
37088
+ order: 250,
37089
+ label: "Move to Proposal",
37090
+ description: "Advance a qualified CRM deal into the proposal stage.",
37091
+ scope: { domain: "sales" },
37092
+ resourceId: "move_to_proposal-workflow",
37093
+ affects: ["crm.deal"]
37094
+ },
37095
+ {
37096
+ id: "move_to_closing",
37097
+ order: 260,
37098
+ label: "Move to Closing",
37099
+ description: "Advance a proposal-stage CRM deal into closing.",
37100
+ scope: { domain: "sales" },
37101
+ resourceId: "move_to_closing-workflow",
37102
+ affects: ["crm.deal"]
37103
+ },
37104
+ {
37105
+ id: "move_to_closed_won",
37106
+ order: 270,
37107
+ label: "Close Won",
37108
+ description: "Mark a CRM deal as closed won.",
37109
+ scope: { domain: "sales" },
37110
+ resourceId: "move_to_closed_won-workflow",
37111
+ affects: ["crm.deal"]
37112
+ },
37113
+ {
37114
+ id: "move_to_closed_lost",
37115
+ order: 280,
37116
+ label: "Close Lost",
37117
+ description: "Mark a CRM deal as closed lost.",
37118
+ scope: { domain: "sales" },
37119
+ resourceId: "move_to_closed_lost-workflow",
37120
+ affects: ["crm.deal"]
37121
+ },
37122
+ {
37123
+ id: "move_to_nurturing",
37124
+ order: 290,
37125
+ label: "Move to Nurturing",
37126
+ description: "Move a CRM deal into nurturing for future follow-up.",
37127
+ scope: { domain: "sales" },
37128
+ resourceId: "move_to_nurturing-workflow",
37129
+ affects: ["crm.deal"]
37130
+ }
37131
+ ];
37132
+ var CRM_ACTION_ENTRIES = Object.fromEntries(
37133
+ CRM_ACTION_ENTRY_INPUTS.map((action) => {
37134
+ const parsed = ActionSchema.parse(action);
37135
+ return [parsed.id, parsed];
37136
+ })
37137
+ );
37138
+ var DEFAULT_ORGANIZATION_MODEL_ACTIONS = {
37139
+ ...LEAD_GEN_ACTION_ENTRIES,
37140
+ ...CRM_ACTION_ENTRIES
37141
+ };
37045
37142
 
37046
37143
  // ../core/src/organization-model/content-kinds/types.ts
37047
37144
  var ContentNodeBaseSchema = external_exports.object({
@@ -37084,6 +37181,398 @@ var ExtensionNodeSchema = external_exports.object({
37084
37181
  data: external_exports.record(external_exports.string(), external_exports.unknown()).optional().meta({ label: "Data" })
37085
37182
  });
37086
37183
 
37184
+ // ../core/src/organization-model/ontology.ts
37185
+ var OntologyKindSchema = external_exports.enum([
37186
+ "object",
37187
+ "link",
37188
+ "action",
37189
+ "catalog",
37190
+ "event",
37191
+ "interface",
37192
+ "value-type",
37193
+ "property",
37194
+ "group",
37195
+ "surface"
37196
+ ]);
37197
+ var SYSTEM_PATH_PATTERN = "[a-z0-9][a-z0-9-]*(?:\\.[a-z0-9][a-z0-9-]*)*";
37198
+ var LOCAL_ID_PATTERN = "[a-z0-9][a-z0-9._-]*";
37199
+ var ONTOLOGY_ID_PATTERN = `^(global|${SYSTEM_PATH_PATTERN}):(${OntologyKindSchema.options.join("|")})\\/(${LOCAL_ID_PATTERN})$`;
37200
+ var ONTOLOGY_ID_REGEX = new RegExp(ONTOLOGY_ID_PATTERN);
37201
+ var OntologyIdSchema = external_exports.string().trim().min(1).max(300).regex(
37202
+ ONTOLOGY_ID_REGEX,
37203
+ "Ontology IDs must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
37204
+ );
37205
+ function parseOntologyId(id) {
37206
+ const normalized = OntologyIdSchema.parse(id);
37207
+ const match = ONTOLOGY_ID_REGEX.exec(normalized);
37208
+ if (match === null) {
37209
+ throw new Error(`Invalid ontology ID "${id}"`);
37210
+ }
37211
+ return {
37212
+ id: normalized,
37213
+ scope: match[1],
37214
+ kind: match[2],
37215
+ localId: match[3],
37216
+ isGlobal: match[1] === "global"
37217
+ };
37218
+ }
37219
+ function formatOntologyId(input) {
37220
+ return OntologyIdSchema.parse(`${input.scope}:${input.kind}/${input.localId}`);
37221
+ }
37222
+ var OntologyReferenceListSchema = external_exports.array(OntologyIdSchema).default([]).optional();
37223
+ var OntologyRecordBaseSchema = external_exports.object({
37224
+ id: OntologyIdSchema,
37225
+ label: external_exports.string().trim().min(1).max(160).optional(),
37226
+ description: external_exports.string().trim().min(1).max(2e3).optional(),
37227
+ ownerSystemId: external_exports.string().trim().min(1).max(200).optional(),
37228
+ aliases: external_exports.array(OntologyIdSchema).optional()
37229
+ }).passthrough();
37230
+ var OntologyObjectTypeSchema = OntologyRecordBaseSchema.extend({
37231
+ properties: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional(),
37232
+ storage: external_exports.record(external_exports.string(), external_exports.unknown()).optional()
37233
+ });
37234
+ var OntologyLinkTypeSchema = OntologyRecordBaseSchema.extend({
37235
+ from: OntologyIdSchema,
37236
+ to: OntologyIdSchema,
37237
+ cardinality: external_exports.string().trim().min(1).max(80).optional(),
37238
+ via: external_exports.string().trim().min(1).max(255).optional()
37239
+ });
37240
+ var OntologyActionTypeSchema = OntologyRecordBaseSchema.extend({
37241
+ actsOn: OntologyReferenceListSchema,
37242
+ input: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional(),
37243
+ effects: external_exports.array(external_exports.record(external_exports.string(), external_exports.unknown())).optional()
37244
+ });
37245
+ var OntologyCatalogTypeSchema = OntologyRecordBaseSchema.extend({
37246
+ kind: external_exports.string().trim().min(1).max(120).optional(),
37247
+ appliesTo: OntologyIdSchema.optional(),
37248
+ entries: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional()
37249
+ });
37250
+ var OntologyEventTypeSchema = OntologyRecordBaseSchema.extend({
37251
+ payload: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional()
37252
+ });
37253
+ var OntologyInterfaceTypeSchema = OntologyRecordBaseSchema.extend({
37254
+ properties: external_exports.record(external_exports.string().trim().min(1).max(200), external_exports.unknown()).optional()
37255
+ });
37256
+ var OntologyValueTypeSchema = OntologyRecordBaseSchema.extend({
37257
+ primitive: external_exports.string().trim().min(1).max(120).optional()
37258
+ });
37259
+ var OntologySharedPropertySchema = OntologyRecordBaseSchema.extend({
37260
+ valueType: OntologyIdSchema.optional(),
37261
+ searchable: external_exports.boolean().optional(),
37262
+ pii: external_exports.boolean().optional()
37263
+ });
37264
+ var OntologyGroupSchema = OntologyRecordBaseSchema.extend({
37265
+ members: OntologyReferenceListSchema
37266
+ });
37267
+ var OntologySurfaceTypeSchema = OntologyRecordBaseSchema.extend({
37268
+ route: external_exports.string().trim().min(1).max(500).optional()
37269
+ });
37270
+ var OntologyScopeSchema = external_exports.object({
37271
+ objectTypes: external_exports.record(OntologyIdSchema, OntologyObjectTypeSchema).default({}).optional(),
37272
+ linkTypes: external_exports.record(OntologyIdSchema, OntologyLinkTypeSchema).default({}).optional(),
37273
+ actionTypes: external_exports.record(OntologyIdSchema, OntologyActionTypeSchema).default({}).optional(),
37274
+ catalogTypes: external_exports.record(OntologyIdSchema, OntologyCatalogTypeSchema).default({}).optional(),
37275
+ eventTypes: external_exports.record(OntologyIdSchema, OntologyEventTypeSchema).default({}).optional(),
37276
+ interfaceTypes: external_exports.record(OntologyIdSchema, OntologyInterfaceTypeSchema).default({}).optional(),
37277
+ valueTypes: external_exports.record(OntologyIdSchema, OntologyValueTypeSchema).default({}).optional(),
37278
+ sharedProperties: external_exports.record(OntologyIdSchema, OntologySharedPropertySchema).default({}).optional(),
37279
+ groups: external_exports.record(OntologyIdSchema, OntologyGroupSchema).default({}).optional(),
37280
+ surfaces: external_exports.record(OntologyIdSchema, OntologySurfaceTypeSchema).default({}).optional()
37281
+ }).default({});
37282
+ var DEFAULT_ONTOLOGY_SCOPE = {
37283
+ valueTypes: {
37284
+ "global:value-type/uuid": {
37285
+ id: "global:value-type/uuid",
37286
+ label: "UUID",
37287
+ primitive: "string"
37288
+ },
37289
+ "global:value-type/text": {
37290
+ id: "global:value-type/text",
37291
+ label: "Text",
37292
+ primitive: "string"
37293
+ },
37294
+ "global:value-type/url": {
37295
+ id: "global:value-type/url",
37296
+ label: "URL",
37297
+ primitive: "string"
37298
+ },
37299
+ "global:value-type/email": {
37300
+ id: "global:value-type/email",
37301
+ label: "Email",
37302
+ primitive: "string"
37303
+ }
37304
+ }
37305
+ };
37306
+ var SCOPE_KIND = {
37307
+ objectTypes: "object",
37308
+ linkTypes: "link",
37309
+ actionTypes: "action",
37310
+ catalogTypes: "catalog",
37311
+ eventTypes: "event",
37312
+ interfaceTypes: "interface",
37313
+ valueTypes: "value-type",
37314
+ sharedProperties: "property",
37315
+ groups: "group",
37316
+ surfaces: "surface"
37317
+ };
37318
+ var SCOPE_KEYS = Object.keys(SCOPE_KIND);
37319
+ function ontologyGraphNodeId(id) {
37320
+ return `ontology:${OntologyIdSchema.parse(id)}`;
37321
+ }
37322
+ function listResolvedOntologyRecords(index) {
37323
+ return SCOPE_KEYS.flatMap((scopeKey) => {
37324
+ const kind = SCOPE_KIND[scopeKey];
37325
+ return Object.entries(index[scopeKey]).sort(([leftId], [rightId]) => leftId.localeCompare(rightId)).map(([id, record2]) => ({
37326
+ id,
37327
+ kind,
37328
+ record: record2
37329
+ }));
37330
+ });
37331
+ }
37332
+ function originFromContext(context) {
37333
+ return {
37334
+ kind: context.kind,
37335
+ source: context.source,
37336
+ path: context.path,
37337
+ ...context.systemPath !== void 0 ? { systemPath: context.systemPath } : {},
37338
+ ...context.legacyId !== void 0 ? { legacyId: context.legacyId } : {}
37339
+ };
37340
+ }
37341
+ function createEmptyIndex() {
37342
+ return {
37343
+ objectTypes: {},
37344
+ linkTypes: {},
37345
+ actionTypes: {},
37346
+ catalogTypes: {},
37347
+ eventTypes: {},
37348
+ interfaceTypes: {},
37349
+ valueTypes: {},
37350
+ sharedProperties: {},
37351
+ groups: {},
37352
+ surfaces: {}
37353
+ };
37354
+ }
37355
+ function sortResolvedOntologyIndex(index) {
37356
+ const sorted = createEmptyIndex();
37357
+ for (const scopeKey of SCOPE_KEYS) {
37358
+ const target = sorted[scopeKey];
37359
+ for (const [id, record2] of Object.entries(index[scopeKey]).sort(
37360
+ ([leftId], [rightId]) => leftId.localeCompare(rightId)
37361
+ )) {
37362
+ target[id] = record2;
37363
+ }
37364
+ }
37365
+ return sorted;
37366
+ }
37367
+ function childSystemsOf(system) {
37368
+ return system.systems ?? system.subsystems ?? {};
37369
+ }
37370
+ function addRecord(index, diagnostics, sourcesById, scopeKey, record2, context) {
37371
+ let parsed;
37372
+ try {
37373
+ parsed = parseOntologyId(record2.id);
37374
+ } catch {
37375
+ diagnostics.push({
37376
+ code: "invalid_ontology_id",
37377
+ message: `Invalid ontology ID "${record2.id}" from ${context.source} at ${context.path.join(".")}`,
37378
+ id: record2.id,
37379
+ path: context.path,
37380
+ source: context.source,
37381
+ origin: originFromContext(context)
37382
+ });
37383
+ return;
37384
+ }
37385
+ const expectedKind = SCOPE_KIND[scopeKey];
37386
+ if (parsed.kind !== expectedKind) {
37387
+ diagnostics.push({
37388
+ code: "ontology_kind_mismatch",
37389
+ message: `Ontology ID "${record2.id}" has kind "${parsed.kind}" but was authored in ${scopeKey} (${expectedKind}) at ${context.path.join(".")}`,
37390
+ id: record2.id,
37391
+ path: context.path,
37392
+ source: context.source,
37393
+ origin: originFromContext(context)
37394
+ });
37395
+ return;
37396
+ }
37397
+ const existing = sourcesById.get(parsed.id);
37398
+ if (existing !== void 0) {
37399
+ diagnostics.push({
37400
+ code: "duplicate_ontology_id",
37401
+ message: `Duplicate ontology ID "${parsed.id}" from ${context.source} at ${context.path.join(".")} conflicts with ${existing.source} at ${existing.path.join(".")}`,
37402
+ id: parsed.id,
37403
+ path: context.path,
37404
+ source: context.source,
37405
+ origin: originFromContext(context),
37406
+ existingSource: existing.source,
37407
+ existingOrigin: originFromContext(existing)
37408
+ });
37409
+ return;
37410
+ }
37411
+ sourcesById.set(parsed.id, context);
37412
+ index[scopeKey][parsed.id] = {
37413
+ ...record2,
37414
+ origin: originFromContext(context)
37415
+ };
37416
+ }
37417
+ function addScope(index, diagnostics, sourcesById, scope, source, path3) {
37418
+ if (scope === void 0) return;
37419
+ for (const scopeKey of SCOPE_KEYS) {
37420
+ const records = scope[scopeKey] ?? {};
37421
+ for (const [key, record2] of Object.entries(records)) {
37422
+ addRecord(index, diagnostics, sourcesById, scopeKey, record2, {
37423
+ source,
37424
+ path: [...path3, scopeKey, key],
37425
+ kind: "authored",
37426
+ systemPath: source.startsWith("system:") ? source.slice("system:".length, -".ontology".length) : void 0
37427
+ });
37428
+ }
37429
+ }
37430
+ }
37431
+ function legacyObjectId(entity) {
37432
+ return formatOntologyId({ scope: entity.ownedBySystemId, kind: "object", localId: entity.id });
37433
+ }
37434
+ function legacyActionOwner(action, entities) {
37435
+ const firstAffectedEntityId = action.affects?.find((entityId) => entities[entityId] !== void 0);
37436
+ if (firstAffectedEntityId !== void 0) {
37437
+ return entities[firstAffectedEntityId].ownedBySystemId;
37438
+ }
37439
+ if (typeof action.scope === "object") {
37440
+ return action.scope.domain;
37441
+ }
37442
+ return "global";
37443
+ }
37444
+ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
37445
+ for (const entity of Object.values(entities)) {
37446
+ const objectType = {
37447
+ id: legacyObjectId(entity),
37448
+ label: entity.label,
37449
+ description: entity.description,
37450
+ ownerSystemId: entity.ownedBySystemId,
37451
+ ...entity.table !== void 0 ? {
37452
+ storage: {
37453
+ kind: "table",
37454
+ table: entity.table
37455
+ }
37456
+ } : {},
37457
+ ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
37458
+ ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
37459
+ };
37460
+ addRecord(index, diagnostics, sourcesById, "objectTypes", objectType, {
37461
+ source: "legacy.entities",
37462
+ path: ["entities", entity.id],
37463
+ kind: "projected",
37464
+ systemPath: entity.ownedBySystemId,
37465
+ legacyId: entity.id
37466
+ });
37467
+ entity.links?.forEach((link, linkIndex) => {
37468
+ const targetEntity = entities[link.toEntity];
37469
+ if (targetEntity === void 0) return;
37470
+ const linkType = {
37471
+ id: formatOntologyId({
37472
+ scope: entity.ownedBySystemId,
37473
+ kind: "link",
37474
+ localId: `${entity.id}-${link.toEntity}-${linkIndex}`
37475
+ }),
37476
+ label: link.label ?? link.kind,
37477
+ ownerSystemId: entity.ownedBySystemId,
37478
+ from: legacyObjectId(entity),
37479
+ to: legacyObjectId(targetEntity),
37480
+ cardinality: link.kind,
37481
+ ...link.via !== void 0 ? { via: link.via } : {}
37482
+ };
37483
+ addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
37484
+ source: "legacy.entities.links",
37485
+ path: ["entities", entity.id, "links", linkIndex],
37486
+ kind: "projected",
37487
+ systemPath: entity.ownedBySystemId,
37488
+ legacyId: `${entity.id}.links.${linkIndex}`
37489
+ });
37490
+ });
37491
+ }
37492
+ }
37493
+ function addLegacyActionProjections(index, diagnostics, sourcesById, actions, entities) {
37494
+ for (const action of Object.values(actions)) {
37495
+ const ownerSystemId = legacyActionOwner(action, entities);
37496
+ const actionType = {
37497
+ id: formatOntologyId({ scope: ownerSystemId, kind: "action", localId: action.id }),
37498
+ label: action.label,
37499
+ description: action.description,
37500
+ ownerSystemId,
37501
+ actsOn: action.affects?.map((entityId) => entities[entityId] ? legacyObjectId(entities[entityId]) : void 0).filter((id) => id !== void 0),
37502
+ ...action.resourceId !== void 0 ? { resourceId: action.resourceId } : {},
37503
+ ...action.invocations !== void 0 ? { invocations: action.invocations } : {},
37504
+ ...action.lifecycle !== void 0 ? { lifecycle: action.lifecycle } : {},
37505
+ legacyActionId: action.id
37506
+ };
37507
+ addRecord(index, diagnostics, sourcesById, "actionTypes", actionType, {
37508
+ source: "legacy.actions",
37509
+ path: ["actions", action.id],
37510
+ kind: "projected",
37511
+ systemPath: ownerSystemId,
37512
+ legacyId: action.id
37513
+ });
37514
+ }
37515
+ }
37516
+ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, schemaPath) {
37517
+ const content = system.content ?? {};
37518
+ for (const [localId, node] of Object.entries(content)) {
37519
+ if (node.kind !== "schema") continue;
37520
+ const entries = Object.fromEntries(
37521
+ Object.entries(content).filter(([, candidate]) => candidate.parentContentId === localId).map(([entryId, candidate]) => [
37522
+ entryId,
37523
+ {
37524
+ label: candidate.label ?? entryId,
37525
+ type: candidate.type,
37526
+ ...candidate.description !== void 0 ? { description: candidate.description } : {},
37527
+ ...candidate.data !== void 0 ? candidate.data : {}
37528
+ }
37529
+ ])
37530
+ );
37531
+ const catalogType = {
37532
+ id: formatOntologyId({ scope: systemPath, kind: "catalog", localId }),
37533
+ label: node.label ?? localId,
37534
+ description: node.description,
37535
+ ownerSystemId: systemPath,
37536
+ kind: node.type,
37537
+ ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
37538
+ ...Object.keys(entries).length > 0 ? { entries } : {},
37539
+ ...node.data !== void 0 ? { data: node.data } : {}
37540
+ };
37541
+ addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
37542
+ source: "legacy.system.content",
37543
+ path: [...schemaPath, "content", localId],
37544
+ kind: "projected",
37545
+ systemPath,
37546
+ legacyId: `${systemPath}:${localId}`
37547
+ });
37548
+ }
37549
+ }
37550
+ function addSystemScopes(index, diagnostics, sourcesById, systems, prefix, schemaPath) {
37551
+ for (const [key, system] of Object.entries(systems)) {
37552
+ const systemPath = prefix ? `${prefix}.${key}` : key;
37553
+ const currentPath = [...schemaPath, key];
37554
+ addScope(index, diagnostics, sourcesById, system.ontology, `system:${systemPath}.ontology`, [
37555
+ ...currentPath,
37556
+ "ontology"
37557
+ ]);
37558
+ addSystemContentProjections(index, diagnostics, sourcesById, systemPath, system, currentPath);
37559
+ addSystemScopes(index, diagnostics, sourcesById, childSystemsOf(system), systemPath, [
37560
+ ...currentPath,
37561
+ system.systems !== void 0 ? "systems" : "subsystems"
37562
+ ]);
37563
+ }
37564
+ }
37565
+ function compileOrganizationOntology(model) {
37566
+ const ontology = createEmptyIndex();
37567
+ const diagnostics = [];
37568
+ const sourcesById = /* @__PURE__ */ new Map();
37569
+ addScope(ontology, diagnostics, sourcesById, model.ontology, "organization.ontology", ["ontology"]);
37570
+ addSystemScopes(ontology, diagnostics, sourcesById, model.systems ?? {}, "", ["systems"]);
37571
+ addLegacyEntityProjections(ontology, diagnostics, sourcesById, model.entities ?? {});
37572
+ addLegacyActionProjections(ontology, diagnostics, sourcesById, model.actions ?? {}, model.entities ?? {});
37573
+ return { ontology: sortResolvedOntologyIndex(ontology), diagnostics };
37574
+ }
37575
+
37087
37576
  // ../core/src/organization-model/domains/systems.ts
37088
37577
  var SystemKindSchema = external_exports.enum(["product", "operational", "platform", "diagnostic"]).meta({ label: "System kind", color: "blue" });
37089
37578
  var SystemLifecycleSchema = external_exports.enum(["draft", "beta", "active", "deprecated", "archived"]).meta({ label: "Lifecycle", color: "teal" });
@@ -37104,6 +37593,17 @@ var SystemUiSchema = external_exports.object({
37104
37593
  icon: IconNameSchema.optional(),
37105
37594
  order: external_exports.number().int().optional()
37106
37595
  });
37596
+ var JsonValueSchema = external_exports.lazy(
37597
+ () => external_exports.union([
37598
+ external_exports.string(),
37599
+ external_exports.number(),
37600
+ external_exports.boolean(),
37601
+ external_exports.null(),
37602
+ external_exports.array(JsonValueSchema),
37603
+ external_exports.record(external_exports.string(), JsonValueSchema)
37604
+ ])
37605
+ );
37606
+ var SystemConfigSchema = external_exports.record(external_exports.string().trim().min(1).max(200), JsonValueSchema).default({}).optional();
37107
37607
  var SystemEntrySchema = external_exports.object({
37108
37608
  /** Stable tenant-defined system id (e.g. "sys.lead-gen" or "sales.crm"). */
37109
37609
  id: SystemIdSchema,
@@ -37149,11 +37649,21 @@ var SystemEntrySchema = external_exports.object({
37149
37649
  /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
37150
37650
  order: external_exports.number(),
37151
37651
  /**
37152
- * System-scoped operational data, co-located with the owning system.
37153
- * Per L1, L3, L13: keyed by local NodeId (the key is the local id; qualified
37154
- * id is `<system-path>:<local-id>`, computed by graph projection).
37155
- * Per L14: every ContentNode carries both `kind` and `type`.
37156
- * Per D2: unregistered (kind, type) pairs parse successfully.
37652
+ * System-local JSON settings and defaults. Strongly typed OM fields,
37653
+ * secrets, credentials, and runtime state stay outside this bucket.
37654
+ */
37655
+ config: SystemConfigSchema,
37656
+ /**
37657
+ * System-owned ontology declarations. `systems` is now the canonical child
37658
+ * key; this scope holds the object, action, catalog, link, event, and
37659
+ * shared contract records owned by this system.
37660
+ */
37661
+ ontology: OntologyScopeSchema.optional(),
37662
+ /**
37663
+ * @deprecated Compatibility-only bridge for old tenant content nodes and
37664
+ * migration readers. New schema/catalog authoring belongs in ontology;
37665
+ * new system-local settings belong in config. Bridge nodes are keyed by
37666
+ * local NodeId and may still project to content-node:* graph IDs.
37157
37667
  */
37158
37668
  content: external_exports.record(external_exports.string().trim().min(1).max(200), ContentNodeSchema).optional(),
37159
37669
  /**
@@ -37163,14 +37673,17 @@ var SystemEntrySchema = external_exports.object({
37163
37673
  * Per Phase 4: `id` and `parentSystemId` fields will be removed in favour of
37164
37674
  * position-derived paths. Both still exist on this schema for backward compat.
37165
37675
  */
37676
+ systems: external_exports.lazy(() => external_exports.record(external_exports.string().trim().min(1).max(100), SystemEntrySchema)).optional(),
37677
+ /** @deprecated Use systems. Accepted as a compatibility alias during the ontology bridge. */
37166
37678
  subsystems: external_exports.lazy(() => external_exports.record(external_exports.string().trim().min(1).max(100), SystemEntrySchema)).optional()
37167
37679
  }).refine((system) => system.label !== void 0 || system.title !== void 0, {
37168
37680
  path: ["label"],
37169
37681
  message: "System must provide label or title"
37170
37682
  }).transform((system) => {
37171
- if (system.status === void 0) return system;
37683
+ const normalizedSystem = system.systems !== void 0 && system.subsystems === void 0 ? { ...system, subsystems: system.systems } : system;
37684
+ if (normalizedSystem.status === void 0) return normalizedSystem;
37172
37685
  console.warn("[organization-model] System.status is deprecated; use System.lifecycle instead.");
37173
- return system.lifecycle === void 0 ? { ...system, lifecycle: system.status } : system;
37686
+ return normalizedSystem.lifecycle === void 0 ? { ...normalizedSystem, lifecycle: normalizedSystem.status } : normalizedSystem;
37174
37687
  });
37175
37688
  var SystemsDomainSchema = external_exports.record(external_exports.string(), SystemEntrySchema).refine((record2) => Object.entries(record2).every(([key, entry]) => entry.id === key), {
37176
37689
  message: "Each system entry id must match its map key"
@@ -37579,6 +38092,7 @@ var ResourceKindSchema = external_exports.enum(["workflow", "agent", "integratio
37579
38092
  var ResourceGovernanceStatusSchema = external_exports.enum(["active", "deprecated", "archived"]).meta({ label: "Governance status", color: "teal" });
37580
38093
  var AgentKindSchema = external_exports.enum(["orchestrator", "specialist", "utility", "platform"]).meta({ label: "Agent kind", color: "violet" });
37581
38094
  var ScriptResourceLanguageSchema = external_exports.enum(["shell", "sql", "typescript", "python"]).meta({ label: "Language" });
38095
+ var CodeReferenceRoleSchema = external_exports.enum(["entrypoint", "handler", "schema", "test", "docs", "config"]).meta({ label: "Code reference role", color: "blue" });
37582
38096
  var ResourceIdSchema = external_exports.string().trim().min(1).max(255).regex(/^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*$/, "Resource IDs must use letters, numbers, -, _, or . separators");
37583
38097
  var EventIdSchema = external_exports.string().trim().min(1).max(300).regex(
37584
38098
  /^[A-Za-z0-9]+(?:[-._][A-Za-z0-9]+)*:[a-z0-9]+(?:[-._][a-z0-9]+)*$/,
@@ -37596,6 +38110,28 @@ var EventDescriptorSchema = EventEmissionDescriptorSchema.extend({
37596
38110
  ownerId: external_exports.union([ResourceIdSchema, ModelIdSchema]),
37597
38111
  ownerKind: external_exports.enum(["resource", "entity"]).meta({ label: "Owner kind" })
37598
38112
  });
38113
+ var ResourceOntologyBindingSchema = external_exports.object({
38114
+ actions: external_exports.array(OntologyIdSchema).optional(),
38115
+ primaryAction: OntologyIdSchema.optional(),
38116
+ reads: external_exports.array(OntologyIdSchema).optional(),
38117
+ writes: external_exports.array(OntologyIdSchema).optional(),
38118
+ usesCatalogs: external_exports.array(OntologyIdSchema).optional(),
38119
+ emits: external_exports.array(OntologyIdSchema).optional()
38120
+ }).superRefine((binding, ctx) => {
38121
+ if (binding.primaryAction === void 0) return;
38122
+ if (binding.actions?.includes(binding.primaryAction)) return;
38123
+ ctx.addIssue({
38124
+ code: external_exports.ZodIssueCode.custom,
38125
+ path: ["primaryAction"],
38126
+ message: "Resource ontology primaryAction must be included in actions"
38127
+ });
38128
+ });
38129
+ var CodeReferenceSchema = external_exports.object({
38130
+ path: external_exports.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
38131
+ role: CodeReferenceRoleSchema,
38132
+ symbol: external_exports.string().trim().min(1).max(200).optional(),
38133
+ description: external_exports.string().trim().min(1).max(300).optional()
38134
+ });
37599
38135
  var ResourceEntryBaseSchema = external_exports.object({
37600
38136
  /** Canonical resource id; runtime resourceId derives from this value. */
37601
38137
  id: ResourceIdSchema,
@@ -37603,14 +38139,24 @@ var ResourceEntryBaseSchema = external_exports.object({
37603
38139
  order: external_exports.number().default(0),
37604
38140
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
37605
38141
  systemPath: SystemPathSchema.meta({ ref: "system" }),
38142
+ /** Executable display title owned by the OM Resource descriptor. */
38143
+ title: LabelSchema.optional(),
38144
+ /** Executable display description owned by the OM Resource descriptor. */
38145
+ description: DescriptionSchema.optional(),
37606
38146
  /** Optional role responsible for maintaining this resource. */
37607
38147
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
37608
- status: ResourceGovernanceStatusSchema
38148
+ status: ResourceGovernanceStatusSchema,
38149
+ /**
38150
+ * Ontology contract bindings for the semantic work this resource performs.
38151
+ * `emits` stays nested here so top-level resource emits descriptors remain
38152
+ * compatible with graph event projection during the bridge.
38153
+ */
38154
+ ontology: ResourceOntologyBindingSchema.optional(),
38155
+ /** Repo-relative implementation breadcrumbs for agents and operators. */
38156
+ codeRefs: external_exports.array(CodeReferenceSchema).default([])
37609
38157
  });
37610
38158
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
37611
38159
  kind: external_exports.literal("workflow"),
37612
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
37613
- actionKey: external_exports.string().trim().min(1).max(255).optional(),
37614
38160
  emits: external_exports.array(EventEmissionDescriptorSchema).optional()
37615
38161
  });
37616
38162
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -37766,19 +38312,29 @@ var KnowledgeTargetKindSchema = external_exports.enum([
37766
38312
  "goal",
37767
38313
  "customer-segment",
37768
38314
  "offering",
38315
+ "ontology",
37769
38316
  // D4: content nodes are a valid knowledge target after compound-domain data moved into system.content
37770
38317
  "content-node"
37771
38318
  ]).meta({ label: "Target kind" });
37772
38319
  var KnowledgeTargetRefSchema = external_exports.object({
37773
38320
  kind: KnowledgeTargetKindSchema,
37774
- // D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'
37775
- // which contains a colon separator and cannot satisfy ModelIdSchema. Use a permissive
37776
- // string schema here; business-logic validation of target existence is done in
37777
- // OrganizationModelSchema.superRefine (knowledgeTargetExists).
38321
+ // D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'.
38322
+ // Ontology targets use the canonical '<scope>:<kind>/<local-id>' ontology id format.
38323
+ // Business-logic validation of target existence is done in OrganizationModelSchema.superRefine.
37778
38324
  id: external_exports.string().trim().min(1).max(300)
38325
+ }).superRefine((target, ctx) => {
38326
+ if (target.kind !== "ontology") return;
38327
+ const result = OntologyIdSchema.safeParse(target.id);
38328
+ if (!result.success) {
38329
+ ctx.addIssue({
38330
+ code: external_exports.ZodIssueCode.custom,
38331
+ path: ["id"],
38332
+ message: "Ontology knowledge targets must use <system-path>:<kind>/<local-id> or global:<kind>/<local-id>"
38333
+ });
38334
+ }
37779
38335
  });
37780
38336
  var LegacyKnowledgeLinkSchema = external_exports.object({
37781
- nodeId: NodeIdStringSchema
38337
+ nodeId: external_exports.union([NodeIdStringSchema, external_exports.templateLiteral(["ontology:", OntologyIdSchema])])
37782
38338
  });
37783
38339
  var CanonicalKnowledgeLinkSchema = external_exports.object({
37784
38340
  target: KnowledgeTargetRefSchema
@@ -37809,6 +38365,8 @@ var OrgKnowledgeNodeSchema = external_exports.object({
37809
38365
  icon: IconNameSchema.optional(),
37810
38366
  /** Canonical documentation URL when body content is a local summary. */
37811
38367
  externalUrl: external_exports.string().trim().url().max(500).optional(),
38368
+ /** Optional generated source file path for local MDX-backed knowledge nodes. */
38369
+ sourceFilePath: external_exports.string().trim().min(1).max(500).optional(),
37812
38370
  /** Raw MDX string. Phase 2 will introduce a structured block format. */
37813
38371
  body: external_exports.string().trim().min(1),
37814
38372
  /**
@@ -37823,6 +38381,75 @@ var OrgKnowledgeNodeSchema = external_exports.object({
37823
38381
  });
37824
38382
  var KnowledgeDomainSchema = external_exports.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
37825
38383
 
38384
+ // ../core/src/organization-model/domains/topology.ts
38385
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
38386
+ 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-----)/;
38387
+ var OmTopologyNodeKindSchema = external_exports.enum([
38388
+ "system",
38389
+ "resource",
38390
+ "ontology",
38391
+ "policy",
38392
+ "role",
38393
+ "trigger",
38394
+ "humanCheckpoint",
38395
+ "externalResource"
38396
+ ]);
38397
+ var OmTopologyRelationshipKindSchema = external_exports.enum(["triggers", "uses", "approval"]);
38398
+ var OmTopologyNodeRefSchema = external_exports.discriminatedUnion("kind", [
38399
+ external_exports.object({ kind: external_exports.literal("system"), id: ModelIdSchema }),
38400
+ external_exports.object({ kind: external_exports.literal("resource"), id: ResourceIdSchema }),
38401
+ external_exports.object({ kind: external_exports.literal("ontology"), id: OntologyIdSchema }),
38402
+ external_exports.object({ kind: external_exports.literal("policy"), id: ModelIdSchema }),
38403
+ external_exports.object({ kind: external_exports.literal("role"), id: ModelIdSchema }),
38404
+ external_exports.object({ kind: external_exports.literal("trigger"), id: ResourceIdSchema }),
38405
+ external_exports.object({ kind: external_exports.literal("humanCheckpoint"), id: ResourceIdSchema }),
38406
+ external_exports.object({ kind: external_exports.literal("externalResource"), id: ResourceIdSchema })
38407
+ ]);
38408
+ var OmTopologyMetadataSchema = external_exports.record(external_exports.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
38409
+ function visit(value, path3) {
38410
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
38411
+ ctx.addIssue({
38412
+ code: external_exports.ZodIssueCode.custom,
38413
+ path: path3,
38414
+ message: "Topology metadata must not contain secret-like values"
38415
+ });
38416
+ return;
38417
+ }
38418
+ if (Array.isArray(value)) {
38419
+ value.forEach((entry, index) => visit(entry, [...path3, index]));
38420
+ return;
38421
+ }
38422
+ if (typeof value !== "object" || value === null) return;
38423
+ Object.entries(value).forEach(([key, entry]) => {
38424
+ if (SecretLikeMetadataKeySchema.test(key)) {
38425
+ ctx.addIssue({
38426
+ code: external_exports.ZodIssueCode.custom,
38427
+ path: [...path3, key],
38428
+ message: `Topology metadata key "${key}" looks secret-like`
38429
+ });
38430
+ }
38431
+ visit(entry, [...path3, key]);
38432
+ });
38433
+ }
38434
+ visit(metadata, []);
38435
+ });
38436
+ var OmTopologyRelationshipSchema = external_exports.object({
38437
+ from: OmTopologyNodeRefSchema,
38438
+ kind: OmTopologyRelationshipKindSchema,
38439
+ to: OmTopologyNodeRefSchema,
38440
+ systemPath: SystemPathSchema.optional(),
38441
+ required: external_exports.boolean().optional(),
38442
+ metadata: OmTopologyMetadataSchema.optional()
38443
+ });
38444
+ var OmTopologyDomainSchema = external_exports.object({
38445
+ version: external_exports.literal(1).default(1),
38446
+ relationships: external_exports.record(external_exports.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
38447
+ }).default({ version: 1, relationships: {} });
38448
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
38449
+ version: 1,
38450
+ relationships: {}
38451
+ };
38452
+
37826
38453
  // ../core/src/organization-model/domains/policies.ts
37827
38454
  var PolicyIdSchema = ModelIdSchema;
37828
38455
  var PolicyApplicabilitySchema = external_exports.object({
@@ -37911,7 +38538,9 @@ var OrganizationModelDomainKeySchema = external_exports.enum([
37911
38538
  "roles",
37912
38539
  "goals",
37913
38540
  "systems",
38541
+ "ontology",
37914
38542
  "resources",
38543
+ "topology",
37915
38544
  "actions",
37916
38545
  "entities",
37917
38546
  "policies",
@@ -37929,7 +38558,9 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
37929
38558
  roles: { version: 1, lastModified: "2026-05-10" },
37930
38559
  goals: { version: 1, lastModified: "2026-05-10" },
37931
38560
  systems: { version: 1, lastModified: "2026-05-10" },
38561
+ ontology: { version: 1, lastModified: "2026-05-14" },
37932
38562
  resources: { version: 1, lastModified: "2026-05-10" },
38563
+ topology: { version: 1, lastModified: "2026-05-14" },
37933
38564
  actions: { version: 1, lastModified: "2026-05-10" },
37934
38565
  entities: { version: 1, lastModified: "2026-05-10" },
37935
38566
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -37943,7 +38574,9 @@ var OrganizationModelDomainMetadataByDomainSchema = external_exports.object({
37943
38574
  roles: OrganizationModelDomainMetadataSchema,
37944
38575
  goals: OrganizationModelDomainMetadataSchema,
37945
38576
  systems: OrganizationModelDomainMetadataSchema,
38577
+ ontology: OrganizationModelDomainMetadataSchema,
37946
38578
  resources: OrganizationModelDomainMetadataSchema,
38579
+ topology: OrganizationModelDomainMetadataSchema,
37947
38580
  actions: OrganizationModelDomainMetadataSchema,
37948
38581
  entities: OrganizationModelDomainMetadataSchema,
37949
38582
  policies: OrganizationModelDomainMetadataSchema,
@@ -37960,7 +38593,9 @@ var OrganizationModelSchemaBase = external_exports.object({
37960
38593
  roles: RolesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ROLES),
37961
38594
  goals: GoalsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_GOALS),
37962
38595
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
38596
+ ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
37963
38597
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
38598
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
37964
38599
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
37965
38600
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
37966
38601
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -37987,13 +38622,16 @@ function asRoleHolderArray(heldBy) {
37987
38622
  function isKnowledgeKindCompatibleWithTarget(knowledgeKind, targetKind) {
37988
38623
  if (knowledgeKind === "reference") return true;
37989
38624
  if (knowledgeKind === "playbook") {
37990
- return ["system", "resource", "stage", "action"].includes(targetKind);
38625
+ return ["system", "resource", "stage", "action", "ontology"].includes(targetKind);
37991
38626
  }
37992
38627
  if (knowledgeKind === "strategy") {
37993
- return ["system", "goal", "offering", "customer-segment"].includes(targetKind);
38628
+ return ["system", "goal", "offering", "customer-segment", "ontology"].includes(targetKind);
37994
38629
  }
37995
38630
  return false;
37996
38631
  }
38632
+ function isRecord(value) {
38633
+ return typeof value === "object" && value !== null && !Array.isArray(value);
38634
+ }
37997
38635
  var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ctx) => {
37998
38636
  function collectAllSystems(systems, prefix = "", schemaPath = ["systems"]) {
37999
38637
  const result = [];
@@ -38001,8 +38639,11 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38001
38639
  const path3 = prefix ? `${prefix}.${key}` : key;
38002
38640
  const currentSchemaPath = [...schemaPath, key];
38003
38641
  result.push({ path: path3, schemaPath: currentSchemaPath, system });
38004
- if (system.subsystems !== void 0) {
38005
- result.push(...collectAllSystems(system.subsystems, path3, [...currentSchemaPath, "subsystems"]));
38642
+ const childSystems = system.systems ?? system.subsystems;
38643
+ if (childSystems !== void 0) {
38644
+ result.push(
38645
+ ...collectAllSystems(childSystems, path3, [...currentSchemaPath, system.systems !== void 0 ? "systems" : "subsystems"])
38646
+ );
38006
38647
  }
38007
38648
  }
38008
38649
  return result;
@@ -38022,7 +38663,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38022
38663
  `System "${system.id}" references unknown parent "${system.parentSystemId}"`
38023
38664
  );
38024
38665
  }
38025
- const hasChildren = Object.keys(system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path3}.`) && !candidate.path.slice(path3.length + 1).includes("."));
38666
+ const hasChildren = Object.keys(system.systems ?? system.subsystems ?? {}).length > 0 || allSystems.some((candidate) => candidate.path.startsWith(`${path3}.`) && !candidate.path.slice(path3.length + 1).includes("."));
38026
38667
  const contributesRoutePath = system.ui?.path !== void 0 || system.path !== void 0 || !hasChildren;
38027
38668
  if (contributesRoutePath) {
38028
38669
  const effectivePath = system.ui?.path ?? system.path ?? defaultSystemPathFor(path3);
@@ -38038,7 +38679,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38038
38679
  }
38039
38680
  }
38040
38681
  if (hasChildren && isLifecycleEnabled(system.lifecycle, system.enabled)) {
38041
- const hasEnabledDescendant = Object.values(system.subsystems ?? {}).some(
38682
+ const hasEnabledDescendant = Object.values(system.systems ?? system.subsystems ?? {}).some(
38042
38683
  (candidate) => isLifecycleEnabled(candidate.lifecycle, candidate.enabled)
38043
38684
  ) || allSystems.some(
38044
38685
  (candidate) => candidate.path.startsWith(`${path3}.`) && !candidate.path.slice(path3.length + 1).includes(".") && isLifecycleEnabled(candidate.system.lifecycle, candidate.system.enabled)
@@ -38283,6 +38924,80 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38283
38924
  const stageIds = /* @__PURE__ */ new Set();
38284
38925
  const actionIds = new Set(Object.keys(model.actions));
38285
38926
  const offeringsById = new Map(Object.entries(model.offerings));
38927
+ const ontologyCompilation = compileOrganizationOntology(model);
38928
+ const ontologyIndexByKind = {
38929
+ object: ontologyCompilation.ontology.objectTypes,
38930
+ link: ontologyCompilation.ontology.linkTypes,
38931
+ action: ontologyCompilation.ontology.actionTypes,
38932
+ catalog: ontologyCompilation.ontology.catalogTypes,
38933
+ event: ontologyCompilation.ontology.eventTypes,
38934
+ interface: ontologyCompilation.ontology.interfaceTypes,
38935
+ "value-type": ontologyCompilation.ontology.valueTypes,
38936
+ property: ontologyCompilation.ontology.sharedProperties,
38937
+ group: ontologyCompilation.ontology.groups,
38938
+ surface: ontologyCompilation.ontology.surfaces
38939
+ };
38940
+ const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
38941
+ function topologyTargetExists(ref) {
38942
+ if (ref.kind === "system") return systemsById.has(ref.id);
38943
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
38944
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
38945
+ if (ref.kind === "policy") return policiesById.has(ref.id);
38946
+ if (ref.kind === "role") return rolesById.has(ref.id);
38947
+ return true;
38948
+ }
38949
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
38950
+ ;
38951
+ ["from", "to"].forEach((side) => {
38952
+ const ref = relationship[side];
38953
+ if (topologyTargetExists(ref)) return;
38954
+ addIssue(
38955
+ ctx,
38956
+ ["topology", "relationships", relationshipId, side],
38957
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
38958
+ );
38959
+ });
38960
+ });
38961
+ const ontologyReferenceKeyKinds = {
38962
+ valueType: "value-type",
38963
+ catalogType: "catalog",
38964
+ objectType: "object",
38965
+ eventType: "event",
38966
+ actionType: "action",
38967
+ linkType: "link",
38968
+ interfaceType: "interface",
38969
+ propertyType: "property",
38970
+ groupType: "group",
38971
+ surfaceType: "surface",
38972
+ stepCatalog: "catalog"
38973
+ };
38974
+ function validateKnownOntologyReferences(ownerId, value, path3, seen = /* @__PURE__ */ new WeakSet()) {
38975
+ if (Array.isArray(value)) {
38976
+ value.forEach((entry, index) => validateKnownOntologyReferences(ownerId, entry, [...path3, index], seen));
38977
+ return;
38978
+ }
38979
+ if (!isRecord(value)) return;
38980
+ if (seen.has(value)) return;
38981
+ seen.add(value);
38982
+ Object.entries(value).forEach(([key, entry]) => {
38983
+ const expectedKind = ontologyReferenceKeyKinds[key];
38984
+ if (expectedKind !== void 0) {
38985
+ if (typeof entry !== "string") {
38986
+ addIssue(ctx, [...path3, key], `Ontology record "${ownerId}" ${key} must be an ontology ID string`);
38987
+ } else if (ontologyIndexByKind[expectedKind][entry] === void 0) {
38988
+ addIssue(
38989
+ ctx,
38990
+ [...path3, key],
38991
+ `Ontology record "${ownerId}" ${key} references unknown ${expectedKind} ontology ID "${entry}"`
38992
+ );
38993
+ }
38994
+ }
38995
+ validateKnownOntologyReferences(ownerId, entry, [...path3, key], seen);
38996
+ });
38997
+ }
38998
+ for (const { id, record: record2 } of listResolvedOntologyRecords(ontologyCompilation.ontology)) {
38999
+ validateKnownOntologyReferences(id, record2, record2.origin.path);
39000
+ }
38286
39001
  Object.values(model.policies).forEach((policy) => {
38287
39002
  policy.appliesTo.systemIds.forEach((systemId, systemIndex) => {
38288
39003
  if (!systemsById.has(systemId)) {
@@ -38336,6 +39051,7 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38336
39051
  if (kind === "goal") return goalsById.has(id);
38337
39052
  if (kind === "customer-segment") return segmentsById.has(id);
38338
39053
  if (kind === "offering") return offeringsById.has(id);
39054
+ if (kind === "ontology") return ontologyIds.has(id);
38339
39055
  return false;
38340
39056
  }
38341
39057
  Object.entries(model.knowledge).forEach(([nodeId2, node]) => {
@@ -38379,6 +39095,34 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38379
39095
  );
38380
39096
  }
38381
39097
  });
39098
+ function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
39099
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
39100
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
39101
+ if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
39102
+ addIssue(
39103
+ ctx,
39104
+ [
39105
+ "resources",
39106
+ resourceId,
39107
+ "ontology",
39108
+ bindingKey,
39109
+ ...Array.isArray(ids) ? [ontologyIndex] : []
39110
+ ],
39111
+ `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
39112
+ );
39113
+ }
39114
+ });
39115
+ }
39116
+ Object.values(model.resources).forEach((resource) => {
39117
+ const binding = resource.ontology;
39118
+ if (binding === void 0) return;
39119
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
39120
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
39121
+ validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
39122
+ validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
39123
+ validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
39124
+ validateResourceOntologyBinding(resource.id, "emits", "event", binding.emits);
39125
+ });
38382
39126
  Object.values(model.roles).forEach((role) => {
38383
39127
  if (role.heldBy === void 0) return;
38384
39128
  asRoleHolderArray(role.heldBy).forEach((holder, holderIndex) => {
@@ -38413,11 +39157,13 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38413
39157
  });
38414
39158
  });
38415
39159
  function validateSystemContent(system, systemPath) {
39160
+ const childSystems = system.systems ?? system.subsystems;
39161
+ const childKey = system.systems !== void 0 ? "systems" : "subsystems";
38416
39162
  const content = system.content;
38417
39163
  if (content === void 0 || Object.keys(content).length === 0) {
38418
- if (system.subsystems !== void 0) {
38419
- Object.entries(system.subsystems).forEach(([childKey, child]) => {
38420
- validateSystemContent(child, [...systemPath, "subsystems", childKey]);
39164
+ if (childSystems !== void 0) {
39165
+ Object.entries(childSystems).forEach(([childLocalId, child]) => {
39166
+ validateSystemContent(child, [...systemPath, childKey, childLocalId]);
38421
39167
  });
38422
39168
  }
38423
39169
  return;
@@ -38473,15 +39219,18 @@ var OrganizationModelSchema = OrganizationModelSchemaBase.superRefine((model, ct
38473
39219
  }
38474
39220
  }
38475
39221
  });
38476
- if (system.subsystems !== void 0) {
38477
- Object.entries(system.subsystems).forEach(([childKey, child]) => {
38478
- validateSystemContent(child, [...systemPath, "subsystems", childKey]);
39222
+ if (childSystems !== void 0) {
39223
+ Object.entries(childSystems).forEach(([childLocalId, child]) => {
39224
+ validateSystemContent(child, [...systemPath, childKey, childLocalId]);
38479
39225
  });
38480
39226
  }
38481
39227
  }
38482
39228
  Object.entries(model.systems).forEach(([systemKey, system]) => {
38483
39229
  validateSystemContent(system, ["systems", systemKey]);
38484
39230
  });
39231
+ for (const diagnostic of ontologyCompilation.diagnostics) {
39232
+ addIssue(ctx, diagnostic.path, diagnostic.message);
39233
+ }
38485
39234
  });
38486
39235
 
38487
39236
  // ../core/src/organization-model/graph/schema.ts
@@ -38502,6 +39251,7 @@ var OrganizationGraphNodeKindSchema = external_exports.enum([
38502
39251
  "surface",
38503
39252
  "navigation-group",
38504
39253
  // Phase 3 preview — Phase 4 populates via graph projection of system.content entries.
39254
+ "ontology",
38505
39255
  "content-node"
38506
39256
  ]);
38507
39257
  var OrganizationGraphEdgeKindSchema = external_exports.enum([
@@ -38515,24 +39265,30 @@ var OrganizationGraphEdgeKindSchema = external_exports.enum([
38515
39265
  "emits",
38516
39266
  "originates_from",
38517
39267
  "triggers",
39268
+ "approval",
38518
39269
  "applies_to",
38519
- "effects"
39270
+ "effects",
39271
+ "actions",
39272
+ "reads",
39273
+ "writes",
39274
+ "uses_catalog"
38520
39275
  ]);
38521
39276
  var OrganizationGraphNodeSchema = external_exports.object({
38522
- id: external_exports.string().trim().min(1).max(200),
39277
+ id: external_exports.string().trim().min(1).max(400),
38523
39278
  kind: OrganizationGraphNodeKindSchema,
38524
39279
  label: LabelSchema,
38525
- sourceId: external_exports.string().trim().min(1).max(255).optional(),
39280
+ sourceId: external_exports.string().trim().min(1).max(400).optional(),
38526
39281
  description: DescriptionSchema.optional(),
38527
39282
  icon: IconNameSchema.optional(),
38528
39283
  enabled: external_exports.boolean().optional(),
39284
+ ontologyKind: external_exports.string().trim().min(1).max(80).optional(),
38529
39285
  resourceType: external_exports.enum(["workflow", "agent", "trigger", "integration", "external", "human_checkpoint", "script"]).optional()
38530
39286
  });
38531
39287
  var OrganizationGraphEdgeSchema = external_exports.object({
38532
- id: external_exports.string().trim().min(1).max(250),
39288
+ id: external_exports.string().trim().min(1).max(900),
38533
39289
  kind: OrganizationGraphEdgeKindSchema,
38534
- sourceId: external_exports.string().trim().min(1).max(200),
38535
- targetId: external_exports.string().trim().min(1).max(200),
39290
+ sourceId: external_exports.string().trim().min(1).max(400),
39291
+ targetId: external_exports.string().trim().min(1).max(400),
38536
39292
  label: external_exports.string().trim().min(1).max(120).optional(),
38537
39293
  relationshipType: external_exports.enum(["triggers", "uses", "approval"]).optional()
38538
39294
  });
@@ -38555,14 +39311,18 @@ function isReservedResourceId(resourceId) {
38555
39311
  }
38556
39312
 
38557
39313
  // ../core/src/organization-model/helpers.ts
39314
+ function childSystemsOf2(system) {
39315
+ return system.systems ?? system.subsystems ?? {};
39316
+ }
38558
39317
  function listAllSystems(model) {
38559
39318
  const results = [];
38560
39319
  function walk(map2, prefix) {
38561
39320
  for (const [localId, system] of Object.entries(map2)) {
38562
39321
  const fullPath = prefix ? `${prefix}.${localId}` : localId;
38563
39322
  results.push({ path: fullPath, system });
38564
- if (system.subsystems) {
38565
- walk(system.subsystems, fullPath);
39323
+ const childSystems = childSystemsOf2(system);
39324
+ if (Object.keys(childSystems).length > 0) {
39325
+ walk(childSystems, fullPath);
38566
39326
  }
38567
39327
  }
38568
39328
  }
@@ -38876,6 +39636,120 @@ function getRuntimeResources(resources) {
38876
39636
  }))
38877
39637
  ];
38878
39638
  }
39639
+ function hasOntologySources(organizationModel) {
39640
+ return organizationModel.ontology !== void 0 || organizationModel.entities !== void 0 || organizationModel.actions !== void 0 || Object.values(organizationModel.systems ?? {}).some(systemHasOntologySource);
39641
+ }
39642
+ function systemHasOntologySource(system) {
39643
+ if (system.ontology !== void 0 || system.content !== void 0 && Object.keys(system.content).length > 0) return true;
39644
+ return Object.values(system.systems ?? system.subsystems ?? {}).some(systemHasOntologySource);
39645
+ }
39646
+ function ontologyIndexForKind(index, kind) {
39647
+ switch (kind) {
39648
+ case "object":
39649
+ return index.objectTypes;
39650
+ case "link":
39651
+ return index.linkTypes;
39652
+ case "action":
39653
+ return index.actionTypes;
39654
+ case "catalog":
39655
+ return index.catalogTypes;
39656
+ case "event":
39657
+ return index.eventTypes;
39658
+ case "interface":
39659
+ return index.interfaceTypes;
39660
+ case "value-type":
39661
+ return index.valueTypes;
39662
+ case "property":
39663
+ return index.sharedProperties;
39664
+ case "group":
39665
+ return index.groups;
39666
+ case "surface":
39667
+ return index.surfaces;
39668
+ }
39669
+ }
39670
+ function sameJson(left, right) {
39671
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
39672
+ }
39673
+ function addOntologyBindingIssues(issues, orgName, resource, ontologyIndex) {
39674
+ const binding = resource.ontology;
39675
+ if (binding === void 0) return;
39676
+ if ((resource.kind === "workflow" || resource.kind === "agent") && (binding.actions?.length ?? 0) === 0) {
39677
+ addGovernanceIssue(
39678
+ issues,
39679
+ "missing-ontology-actions",
39680
+ orgName,
39681
+ resource.id,
39682
+ `[${orgName}] Resource '${resource.id}' declares ontology bindings but no ontology actions.`
39683
+ );
39684
+ }
39685
+ if (binding.primaryAction !== void 0 && !binding.actions?.includes(binding.primaryAction)) {
39686
+ addGovernanceIssue(
39687
+ issues,
39688
+ "primary-action-mismatch",
39689
+ orgName,
39690
+ resource.id,
39691
+ `[${orgName}] Resource '${resource.id}' primaryAction '${binding.primaryAction}' must be included in ontology.actions.`
39692
+ );
39693
+ }
39694
+ if (ontologyIndex === void 0) return;
39695
+ const validateRefs = (bindingKey, expectedKind, refs) => {
39696
+ const values = refs === void 0 ? [] : Array.isArray(refs) ? refs : [refs];
39697
+ const index = ontologyIndexForKind(ontologyIndex, expectedKind);
39698
+ for (const ref of values) {
39699
+ if (index[ref] !== void 0) continue;
39700
+ addGovernanceIssue(
39701
+ issues,
39702
+ "ontology-reference-missing",
39703
+ orgName,
39704
+ resource.id,
39705
+ `[${orgName}] Resource '${resource.id}' ontology.${bindingKey} references missing ${expectedKind} ontology record '${ref}'.`
39706
+ );
39707
+ }
39708
+ };
39709
+ validateRefs("actions", "action", binding.actions);
39710
+ validateRefs("primaryAction", "action", binding.primaryAction);
39711
+ validateRefs("reads", "object", binding.reads);
39712
+ validateRefs("writes", "object", binding.writes);
39713
+ validateRefs("usesCatalogs", "catalog", binding.usesCatalogs);
39714
+ validateRefs("emits", "event", binding.emits);
39715
+ }
39716
+ function addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex) {
39717
+ const relationships = organizationModel.topology?.relationships;
39718
+ if (relationships === void 0) return;
39719
+ const rolesById = new Set(Object.keys(organizationModel.roles ?? {}));
39720
+ const policiesById = new Set(Object.keys(organizationModel.policies ?? {}));
39721
+ const triggerIds = new Set(deployment.triggers?.map((trigger) => trigger.resourceId) ?? []);
39722
+ const humanCheckpointIds = new Set(deployment.humanCheckpoints?.map((checkpoint) => checkpoint.resourceId) ?? []);
39723
+ const externalResourceIds = new Set(deployment.externalResources?.map((external) => external.resourceId) ?? []);
39724
+ const topologyRefExists = (ref) => {
39725
+ if (ref.kind === "system") return systemsById.has(ref.id);
39726
+ if (ref.kind === "resource") return omResourcesById.has(ref.id);
39727
+ if (ref.kind === "policy") return policiesById.has(ref.id);
39728
+ if (ref.kind === "role") return rolesById.has(ref.id);
39729
+ if (ref.kind === "trigger") return triggerIds.has(ref.id);
39730
+ if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
39731
+ if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
39732
+ if (ref.kind === "ontology") {
39733
+ if (ontologyIndex === void 0) return true;
39734
+ return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
39735
+ }
39736
+ return false;
39737
+ };
39738
+ for (const [relationshipId, relationship] of Object.entries(relationships)) {
39739
+ ;
39740
+ ["from", "to"].forEach((side) => {
39741
+ const ref = relationship[side];
39742
+ if (topologyRefExists(ref)) return;
39743
+ addGovernanceIssue(
39744
+ issues,
39745
+ "topology-reference-missing",
39746
+ orgName,
39747
+ ref.id,
39748
+ `[${orgName}] Topology relationship '${relationshipId}' ${side} references missing ${ref.kind} '${ref.id}'.`
39749
+ );
39750
+ });
39751
+ }
39752
+ }
38879
39753
  function validateResourceGovernance(orgName, deployment, organizationModel = deployment.organizationModel, options = {}) {
38880
39754
  const mode = getResourceValidatorMode(options.mode);
38881
39755
  const omResourcesMap = organizationModel?.resources;
@@ -38891,6 +39765,17 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
38891
39765
  const omResourcesById = new Map(activeOmResources.map((resource) => [resource.id, resource]));
38892
39766
  const runtimeResources = getRuntimeResources(deployment);
38893
39767
  const runtimeResourcesById = new Map(runtimeResources.map((resource) => [resource.resourceId, resource]));
39768
+ const ontologyCompilation = hasOntologySources(organizationModel) ? compileOrganizationOntology(organizationModel) : void 0;
39769
+ const ontologyIndex = ontologyCompilation?.ontology;
39770
+ for (const diagnostic of ontologyCompilation?.diagnostics ?? []) {
39771
+ addGovernanceIssue(
39772
+ issues,
39773
+ "ontology-reference-missing",
39774
+ orgName,
39775
+ diagnostic.id,
39776
+ `[${orgName}] ${diagnostic.message}`
39777
+ );
39778
+ }
38894
39779
  for (const resource of activeOmResources) {
38895
39780
  if (!systemsById.has(resource.systemPath)) {
38896
39781
  addGovernanceIssue(
@@ -38930,6 +39815,16 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
38930
39815
  `[${orgName}] Resource '${resource.id}' system mismatch: code descriptor has '${runtimeResource.descriptor.systemPath}', OM has '${resource.systemPath}'.`
38931
39816
  );
38932
39817
  }
39818
+ if (runtimeResource.descriptor && !sameJson(runtimeResource.descriptor.ontology, resource.ontology)) {
39819
+ addGovernanceIssue(
39820
+ issues,
39821
+ "descriptor-mismatch",
39822
+ orgName,
39823
+ resource.id,
39824
+ `[${orgName}] Resource '${resource.id}' ontology descriptor mismatch between code and OM.`
39825
+ );
39826
+ }
39827
+ addOntologyBindingIssues(issues, orgName, resource, ontologyIndex);
38933
39828
  }
38934
39829
  for (const runtimeResource of runtimeResources) {
38935
39830
  const omResource = omResourcesById.get(runtimeResource.resourceId);
@@ -38971,6 +39866,7 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
38971
39866
  );
38972
39867
  }
38973
39868
  }
39869
+ addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex);
38974
39870
  emitGovernanceIssues(issues, mode, options.onWarning);
38975
39871
  return {
38976
39872
  valid: issues.length === 0,
@@ -42519,14 +43415,14 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42519
43415
  label: "Dashboard",
42520
43416
  path: "/",
42521
43417
  surfaceType: "dashboard",
42522
- icon: "feature.dashboard",
43418
+ icon: "dashboard",
42523
43419
  order: 10,
42524
43420
  targets: { systems: ["dashboard"] }
42525
43421
  },
42526
43422
  business: {
42527
43423
  type: "group",
42528
43424
  label: "Business",
42529
- icon: "feature.business",
43425
+ icon: "business",
42530
43426
  order: 20,
42531
43427
  children: {
42532
43428
  sales: {
@@ -42534,7 +43430,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42534
43430
  label: "Sales",
42535
43431
  path: "/sales",
42536
43432
  surfaceType: "page",
42537
- icon: "feature.sales",
43433
+ icon: "sales",
42538
43434
  order: 10,
42539
43435
  targets: { systems: ["sales"] }
42540
43436
  },
@@ -42543,7 +43439,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42543
43439
  label: "Clients",
42544
43440
  path: "/clients",
42545
43441
  surfaceType: "list",
42546
- icon: "feature.projects",
43442
+ icon: "projects",
42547
43443
  order: 20,
42548
43444
  targets: { systems: ["clients"] }
42549
43445
  },
@@ -42552,7 +43448,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42552
43448
  label: "Projects",
42553
43449
  path: "/projects",
42554
43450
  surfaceType: "page",
42555
- icon: "feature.projects",
43451
+ icon: "projects",
42556
43452
  order: 30,
42557
43453
  targets: { systems: ["projects"] }
42558
43454
  }
@@ -42561,7 +43457,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42561
43457
  operations: {
42562
43458
  type: "group",
42563
43459
  label: "Operations",
42564
- icon: "feature.operations",
43460
+ icon: "operations",
42565
43461
  order: 30,
42566
43462
  children: {
42567
43463
  "operations-overview": {
@@ -42609,7 +43505,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42609
43505
  monitoring: {
42610
43506
  type: "group",
42611
43507
  label: "Monitoring",
42612
- icon: "feature.monitoring",
43508
+ icon: "monitoring",
42613
43509
  order: 40,
42614
43510
  children: {
42615
43511
  "monitoring-overview": {
@@ -42671,36 +43567,19 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42671
43567
  }
42672
43568
  },
42673
43569
  knowledge: {
42674
- type: "group",
42675
- label: "Knowledge",
42676
- icon: "feature.knowledge",
42677
- order: 50,
42678
- children: {
42679
- "knowledge-base": {
42680
- type: "surface",
42681
- label: "Knowledge Base",
42682
- path: "/knowledge",
42683
- surfaceType: "page",
42684
- order: 10,
42685
- targets: { systems: ["knowledge.base"] }
42686
- },
42687
- "knowledge-command-view": {
42688
- type: "surface",
42689
- label: "Command View",
42690
- path: "/knowledge/command-view",
42691
- surfaceType: "graph",
42692
- order: 20,
42693
- targets: { systems: ["knowledge.command-view"] },
42694
- devOnly: true
42695
- }
42696
- }
43570
+ type: "surface",
43571
+ label: "Knowledge Base",
43572
+ path: "/knowledge",
43573
+ surfaceType: "page",
43574
+ icon: "knowledge",
43575
+ order: 50
42697
43576
  }
42698
43577
  },
42699
43578
  bottom: {
42700
43579
  settings: {
42701
43580
  type: "group",
42702
43581
  label: "Settings",
42703
- icon: "feature.settings",
43582
+ icon: "settings",
42704
43583
  order: 10,
42705
43584
  children: {
42706
43585
  "settings-account": {
@@ -42772,7 +43651,7 @@ var DEFAULT_ORGANIZATION_MODEL_NAVIGATION = {
42772
43651
  admin: {
42773
43652
  type: "group",
42774
43653
  label: "Admin",
42775
- icon: "feature.admin",
43654
+ icon: "admin",
42776
43655
  order: 20,
42777
43656
  children: {
42778
43657
  "admin-dashboard": {
@@ -42852,7 +43731,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42852
43731
  enabled: true,
42853
43732
  lifecycle: "active",
42854
43733
  path: "/",
42855
- icon: "feature.dashboard"
43734
+ icon: "dashboard"
42856
43735
  },
42857
43736
  platform: {
42858
43737
  id: "platform",
@@ -42862,7 +43741,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42862
43741
  enabled: true,
42863
43742
  lifecycle: "active",
42864
43743
  color: "cyan",
42865
- icon: "feature.platform"
43744
+ icon: "platform"
42866
43745
  },
42867
43746
  finance: {
42868
43747
  id: "finance",
@@ -42872,7 +43751,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42872
43751
  enabled: true,
42873
43752
  lifecycle: "active",
42874
43753
  color: "green",
42875
- icon: "feature.finance"
43754
+ icon: "finance"
42876
43755
  },
42877
43756
  sales: {
42878
43757
  id: "sales",
@@ -42882,7 +43761,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42882
43761
  enabled: true,
42883
43762
  lifecycle: "active",
42884
43763
  color: "blue",
42885
- icon: "feature.sales",
43764
+ icon: "sales",
42886
43765
  path: "/sales"
42887
43766
  },
42888
43767
  "sales.crm": {
@@ -42892,8 +43771,12 @@ var DEFAULT_ORGANIZATION_MODEL = {
42892
43771
  description: "Relationship pipeline and deal management",
42893
43772
  enabled: true,
42894
43773
  lifecycle: "active",
43774
+ actions: Object.values(CRM_ACTION_ENTRIES).map((action) => ({
43775
+ actionId: action.id,
43776
+ intent: "exposes"
43777
+ })),
42895
43778
  color: "blue",
42896
- icon: "feature.crm",
43779
+ icon: "crm",
42897
43780
  path: "/crm"
42898
43781
  },
42899
43782
  "sales.lead-gen": {
@@ -42903,12 +43786,12 @@ var DEFAULT_ORGANIZATION_MODEL = {
42903
43786
  description: "Prospecting, qualification, and outreach preparation",
42904
43787
  enabled: true,
42905
43788
  lifecycle: "active",
42906
- actions: Object.values(DEFAULT_ORGANIZATION_MODEL_ACTIONS).map((action) => ({
43789
+ actions: Object.values(LEAD_GEN_ACTION_ENTRIES).map((action) => ({
42907
43790
  actionId: action.id,
42908
43791
  intent: "exposes"
42909
43792
  })),
42910
43793
  color: "cyan",
42911
- icon: "feature.lead-gen",
43794
+ icon: "lead-gen",
42912
43795
  path: "/lead-gen"
42913
43796
  },
42914
43797
  projects: {
@@ -42919,7 +43802,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42919
43802
  enabled: true,
42920
43803
  lifecycle: "active",
42921
43804
  color: "orange",
42922
- icon: "feature.projects",
43805
+ icon: "projects",
42923
43806
  path: "/projects"
42924
43807
  },
42925
43808
  clients: {
@@ -42930,7 +43813,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42930
43813
  enabled: true,
42931
43814
  lifecycle: "active",
42932
43815
  color: "orange",
42933
- icon: "feature.projects",
43816
+ icon: "projects",
42934
43817
  path: "/clients"
42935
43818
  },
42936
43819
  operations: {
@@ -42941,7 +43824,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
42941
43824
  enabled: true,
42942
43825
  lifecycle: "active",
42943
43826
  color: "violet",
42944
- icon: "feature.operations"
43827
+ icon: "operations"
42945
43828
  },
42946
43829
  "knowledge.command-view": {
42947
43830
  id: "knowledge.command-view",
@@ -43007,7 +43890,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43007
43890
  enabled: true,
43008
43891
  lifecycle: "active",
43009
43892
  path: "/monitoring/calendar",
43010
- icon: "feature.calendar"
43893
+ icon: "calendar"
43011
43894
  },
43012
43895
  "monitoring.activity-log": {
43013
43896
  id: "monitoring.activity-log",
@@ -43063,7 +43946,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43063
43946
  label: "Settings",
43064
43947
  enabled: true,
43065
43948
  lifecycle: "active",
43066
- icon: "feature.settings"
43949
+ icon: "settings"
43067
43950
  },
43068
43951
  "settings.account": {
43069
43952
  id: "settings.account",
@@ -43136,7 +44019,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43136
44019
  enabled: true,
43137
44020
  lifecycle: "active",
43138
44021
  path: "/admin",
43139
- icon: "feature.admin",
44022
+ icon: "admin",
43140
44023
  requiresAdmin: true
43141
44024
  },
43142
44025
  "admin.system-health": {
@@ -43186,7 +44069,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43186
44069
  enabled: true,
43187
44070
  lifecycle: "active",
43188
44071
  path: "/archive",
43189
- icon: "feature.archive",
44072
+ icon: "archive",
43190
44073
  devOnly: true
43191
44074
  },
43192
44075
  "archive.agent-chat": {
@@ -43221,7 +44104,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
43221
44104
  enabled: true,
43222
44105
  lifecycle: "active",
43223
44106
  color: "teal",
43224
- icon: "feature.knowledge"
44107
+ icon: "knowledge"
43225
44108
  },
43226
44109
  "knowledge.base": {
43227
44110
  id: "knowledge.base",
@@ -43232,11 +44115,14 @@ var DEFAULT_ORGANIZATION_MODEL = {
43232
44115
  path: "/knowledge"
43233
44116
  }
43234
44117
  },
44118
+ ontology: DEFAULT_ONTOLOGY_SCOPE,
43235
44119
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
44120
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
43236
44121
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
43237
44122
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
43238
44123
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
43239
- // Phase 4 (D1): statuses top-level field removed; status data lives in system.content.
44124
+ // Phase 4 (D1): statuses top-level field removed; bridge status mirrors may
44125
+ // still project from System.content, but primary authoring belongs in ontology.
43240
44126
  knowledge: DEFAULT_ORGANIZATION_MODEL_KNOWLEDGE
43241
44127
  };
43242
44128
 
@@ -43286,7 +44172,7 @@ function getAllBuildTemplates(model) {
43286
44172
  label: s.label ?? stepLocalId,
43287
44173
  ...s.description ? { description: s.description } : {},
43288
44174
  // Pass through all data fields — template-step payload is richer than Pipeline;
43289
- // Wave 2 authors the canonical shape; Wave 4 verifies round-trip fidelity.
44175
+ // Bridge readers preserve the historical shape for round-trip fidelity.
43290
44176
  ...sd
43291
44177
  };
43292
44178
  });
@@ -43450,6 +44336,20 @@ function invocationLabel(invocation) {
43450
44336
  function eventNodeId(eventId) {
43451
44337
  return nodeId("event", eventId);
43452
44338
  }
44339
+ function ontologyLabel(id, label) {
44340
+ return label ?? parseOntologyId(id).localId;
44341
+ }
44342
+ function pushOntologyBindingEdges(edges, edgeIds, resourceNodeId, kind, ids) {
44343
+ ids?.forEach((ontologyId) => {
44344
+ const targetId = ontologyGraphNodeId(ontologyId);
44345
+ pushUniqueEdge(edges, edgeIds, {
44346
+ id: edgeId(kind, resourceNodeId, targetId),
44347
+ kind,
44348
+ sourceId: resourceNodeId,
44349
+ targetId
44350
+ });
44351
+ });
44352
+ }
43453
44353
  function buildResourceEventDescriptor(resourceId, emission) {
43454
44354
  return {
43455
44355
  ...emission,
@@ -43497,6 +44397,7 @@ function buildOrganizationGraph(input) {
43497
44397
  const organizationModelResourceIds = new Set(Object.keys(organizationModel.resources));
43498
44398
  const actionIdsByInvocation = /* @__PURE__ */ new Map();
43499
44399
  const projectedEventNodeIdsByEventId = /* @__PURE__ */ new Map();
44400
+ const ontologyCompilation = compileOrganizationOntology(organizationModel);
43500
44401
  const organizationNode = {
43501
44402
  id: nodeId("organization"),
43502
44403
  kind: "organization",
@@ -43511,6 +44412,32 @@ function buildOrganizationGraph(input) {
43511
44412
  }
43512
44413
  const validSystemRefs = new Set(systemPathByRef.keys());
43513
44414
  const systemNodeId = (systemRef) => nodeId("system", systemPathByRef.get(systemRef) ?? systemRef);
44415
+ function topologyNodeId(ref) {
44416
+ if (ref.kind === "system") return systemNodeId(ref.id);
44417
+ if (ref.kind === "resource") return nodeId("resource", ref.id);
44418
+ if (ref.kind === "ontology") return ontologyGraphNodeId(ref.id);
44419
+ if (ref.kind === "policy") return nodeId("policy", ref.id);
44420
+ if (ref.kind === "role") return nodeId("role", ref.id);
44421
+ return nodeId("resource", ref.id);
44422
+ }
44423
+ function ensureTopologyNode(ref) {
44424
+ const id = topologyNodeId(ref);
44425
+ if (nodeIds.has(id)) return id;
44426
+ if (ref.kind === "resource") {
44427
+ ensureResourceNode(nodes, nodeIds, resourceNodesById, ref.id);
44428
+ return id;
44429
+ }
44430
+ if (ref.kind === "trigger" || ref.kind === "humanCheckpoint" || ref.kind === "externalResource") {
44431
+ pushUniqueNode(nodes, nodeIds, {
44432
+ id,
44433
+ kind: "resource",
44434
+ label: ref.id,
44435
+ sourceId: ref.id,
44436
+ resourceType: ref.kind === "trigger" ? "trigger" : ref.kind === "humanCheckpoint" ? "human_checkpoint" : "external"
44437
+ });
44438
+ }
44439
+ return id;
44440
+ }
43514
44441
  for (const { path: path3, system } of systemsWithPaths.sort((a, b) => a.path.localeCompare(b.path))) {
43515
44442
  const id = nodeId("system", path3);
43516
44443
  pushUniqueNode(nodes, nodeIds, {
@@ -43538,6 +44465,78 @@ function buildOrganizationGraph(input) {
43538
44465
  });
43539
44466
  }
43540
44467
  }
44468
+ for (const { id: ontologyId, kind, record: record2 } of listResolvedOntologyRecords(ontologyCompilation.ontology).sort(
44469
+ (a, b) => a.id.localeCompare(b.id)
44470
+ )) {
44471
+ const id = ontologyGraphNodeId(ontologyId);
44472
+ const parsedId = parseOntologyId(ontologyId);
44473
+ pushUniqueNode(nodes, nodeIds, {
44474
+ id,
44475
+ kind: "ontology",
44476
+ label: ontologyLabel(ontologyId, record2.label),
44477
+ sourceId: ontologyId,
44478
+ description: record2.description,
44479
+ ontologyKind: kind
44480
+ });
44481
+ const ownerSystemId = record2.ownerSystemId ?? (parsedId.isGlobal ? void 0 : parsedId.scope);
44482
+ if (ownerSystemId !== void 0 && validSystemRefs.has(ownerSystemId)) {
44483
+ pushUniqueEdge(edges, edgeIds, {
44484
+ id: edgeId("contains", systemNodeId(ownerSystemId), id, `ontology-${kind}`),
44485
+ kind: "contains",
44486
+ sourceId: systemNodeId(ownerSystemId),
44487
+ targetId: id
44488
+ });
44489
+ } else {
44490
+ pushUniqueEdge(edges, edgeIds, {
44491
+ id: edgeId("contains", organizationNode.id, id, `ontology-${kind}`),
44492
+ kind: "contains",
44493
+ sourceId: organizationNode.id,
44494
+ targetId: id
44495
+ });
44496
+ }
44497
+ if (kind === "link") {
44498
+ const link = record2;
44499
+ pushUniqueEdge(edges, edgeIds, {
44500
+ id: edgeId("links", ontologyGraphNodeId(link.from), ontologyGraphNodeId(link.to), ontologyId),
44501
+ kind: "links",
44502
+ sourceId: ontologyGraphNodeId(link.from),
44503
+ targetId: ontologyGraphNodeId(link.to),
44504
+ label: link.label ?? parsedId.localId
44505
+ });
44506
+ }
44507
+ if (kind === "action") {
44508
+ const action = record2;
44509
+ for (const targetOntologyId of action.actsOn ?? []) {
44510
+ pushUniqueEdge(edges, edgeIds, {
44511
+ id: edgeId("affects", id, ontologyGraphNodeId(targetOntologyId), ontologyId),
44512
+ kind: "affects",
44513
+ sourceId: id,
44514
+ targetId: ontologyGraphNodeId(targetOntologyId)
44515
+ });
44516
+ }
44517
+ }
44518
+ if (kind === "catalog") {
44519
+ const catalog = record2;
44520
+ if (catalog.appliesTo === void 0) continue;
44521
+ pushUniqueEdge(edges, edgeIds, {
44522
+ id: edgeId("applies_to", id, ontologyGraphNodeId(catalog.appliesTo), ontologyId),
44523
+ kind: "applies_to",
44524
+ sourceId: id,
44525
+ targetId: ontologyGraphNodeId(catalog.appliesTo)
44526
+ });
44527
+ }
44528
+ if (kind === "group") {
44529
+ const group = record2;
44530
+ for (const memberOntologyId of group.members ?? []) {
44531
+ pushUniqueEdge(edges, edgeIds, {
44532
+ id: edgeId("contains", id, ontologyGraphNodeId(memberOntologyId), ontologyId),
44533
+ kind: "contains",
44534
+ sourceId: id,
44535
+ targetId: ontologyGraphNodeId(memberOntologyId)
44536
+ });
44537
+ }
44538
+ }
44539
+ }
43541
44540
  for (const role of Object.values(organizationModel.roles).sort((a, b) => a.id.localeCompare(b.id))) {
43542
44541
  const id = nodeId("role", role.id);
43543
44542
  pushUniqueNode(nodes, nodeIds, {
@@ -43589,7 +44588,7 @@ function buildOrganizationGraph(input) {
43589
44588
  targetId: id
43590
44589
  });
43591
44590
  for (const link of node.links) {
43592
- const targetId = link.target.kind === "system" ? systemNodeId(link.target.id) : link.nodeId;
44591
+ const targetId = link.target.kind === "system" ? systemNodeId(link.target.id) : link.target.kind === "ontology" ? ontologyGraphNodeId(link.target.id) : link.nodeId;
43593
44592
  pushUniqueEdge(edges, edgeIds, {
43594
44593
  id: edgeId("governs", id, targetId),
43595
44594
  kind: "governs",
@@ -43754,6 +44753,11 @@ function buildOrganizationGraph(input) {
43754
44753
  targetId: resourceNode.id
43755
44754
  });
43756
44755
  }
44756
+ pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "actions", resource.ontology?.actions);
44757
+ pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "reads", resource.ontology?.reads);
44758
+ pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "writes", resource.ontology?.writes);
44759
+ pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "uses_catalog", resource.ontology?.usesCatalogs);
44760
+ pushOntologyBindingEdges(edges, edgeIds, resourceNode.id, "emits", resource.ontology?.emits);
43757
44761
  if (resource.kind === "workflow" || resource.kind === "agent") {
43758
44762
  for (const emission of resource.emits ?? []) {
43759
44763
  pushEventProjection(
@@ -43883,6 +44887,19 @@ function buildOrganizationGraph(input) {
43883
44887
  }
43884
44888
  }
43885
44889
  }
44890
+ for (const [relationshipId, relationship] of Object.entries(organizationModel.topology.relationships).sort(
44891
+ ([a], [b]) => a.localeCompare(b)
44892
+ )) {
44893
+ const sourceId = ensureTopologyNode(relationship.from);
44894
+ const targetId = ensureTopologyNode(relationship.to);
44895
+ pushUniqueEdge(edges, edgeIds, {
44896
+ id: edgeId(relationship.kind, sourceId, targetId, `topology-${relationshipId}`),
44897
+ kind: relationship.kind,
44898
+ sourceId,
44899
+ targetId,
44900
+ relationshipType: relationship.kind
44901
+ });
44902
+ }
43886
44903
  for (const segment of Object.values(organizationModel.customers).sort(
43887
44904
  (a, b) => a.order - b.order || a.id.localeCompare(b.id)
43888
44905
  )) {
@@ -44317,7 +45334,7 @@ function wrapAction(commandName, fn) {
44317
45334
  // package.json
44318
45335
  var package_default = {
44319
45336
  name: "@elevasis/sdk",
44320
- version: "1.21.0",
45337
+ version: "1.22.1",
44321
45338
  description: "SDK for building Elevasis organization resources",
44322
45339
  type: "module",
44323
45340
  bin: {
@@ -46888,6 +47905,16 @@ function registerProjectCommands(program3) {
46888
47905
  function toGraphNodeId(omNodeId) {
46889
47906
  return `knowledge:${omNodeId}`;
46890
47907
  }
47908
+ function toTargetGraphNodeId(nodeId2) {
47909
+ if (nodeId2.startsWith("system:") || nodeId2.startsWith("knowledge:") || nodeId2.startsWith("resource:") || nodeId2.startsWith("content-node:") || nodeId2.startsWith("ontology:")) {
47910
+ return nodeId2;
47911
+ }
47912
+ const ontologyId = OntologyIdSchema.safeParse(nodeId2);
47913
+ if (ontologyId.success) {
47914
+ return ontologyGraphNodeId(ontologyId.data);
47915
+ }
47916
+ return `system:${nodeId2}`;
47917
+ }
46891
47918
  function buildKnowledgeSourceIdMap(graph) {
46892
47919
  const map2 = /* @__PURE__ */ new Map();
46893
47920
  for (const node of graph.nodes) {
@@ -46913,6 +47940,22 @@ function bySystem(graph, systemId, knowledgeNodes) {
46913
47940
  }
46914
47941
  return knowledgeNodes.filter((n) => matchingOmIds.has(n.id));
46915
47942
  }
47943
+ function byOntology(graph, ontologyId, knowledgeNodes) {
47944
+ const targetGraphNodeId = toTargetGraphNodeId(ontologyId);
47945
+ const governingKnowledgeNodeIds = /* @__PURE__ */ new Set();
47946
+ for (const edge of graph.edges) {
47947
+ if (edge.kind === "governs" && edge.targetId === targetGraphNodeId && edge.sourceId.startsWith("knowledge:")) {
47948
+ governingKnowledgeNodeIds.add(edge.sourceId);
47949
+ }
47950
+ }
47951
+ const sourceIdMap = buildKnowledgeSourceIdMap(graph);
47952
+ const matchingOmIds = /* @__PURE__ */ new Set();
47953
+ for (const graphNodeId of governingKnowledgeNodeIds) {
47954
+ const omId = sourceIdMap.get(graphNodeId);
47955
+ if (omId) matchingOmIds.add(omId);
47956
+ }
47957
+ return knowledgeNodes.filter((n) => matchingOmIds.has(n.id));
47958
+ }
46916
47959
  function byKind(_graph, kind, knowledgeNodes) {
46917
47960
  return knowledgeNodes.filter((n) => n.kind === kind);
46918
47961
  }
@@ -46930,7 +47973,7 @@ function governs(graph, nodeId2) {
46930
47973
  return results;
46931
47974
  }
46932
47975
  function governedBy(graph, nodeId2) {
46933
- const targetId = nodeId2.startsWith("system:") || nodeId2.startsWith("knowledge:") || nodeId2.startsWith("resource:") ? nodeId2 : `system:${nodeId2}`;
47976
+ const targetId = toTargetGraphNodeId(nodeId2);
46934
47977
  const results = [];
46935
47978
  for (const edge of graph.edges) {
46936
47979
  if (edge.kind === "governs" && edge.targetId === targetId) {
@@ -46958,6 +48001,12 @@ function parsePath(pathString) {
46958
48001
  }
46959
48002
  return { mount: "by-system", args: [rest.join("/")] };
46960
48003
  }
48004
+ if (first === "by-ontology") {
48005
+ if (rest.length === 0) {
48006
+ throw new Error(`parsePath: /by-ontology requires an ontologyId argument, got: "${pathString}"`);
48007
+ }
48008
+ return { mount: "by-ontology", args: [rest.join("/")] };
48009
+ }
46961
48010
  if (first === "by-kind") {
46962
48011
  if (rest.length === 0) {
46963
48012
  throw new Error(`parsePath: /by-kind requires a kind argument, got: "${pathString}"`);
@@ -47078,7 +48127,7 @@ async function loadOrgModel(projectRoot) {
47078
48127
  // src/cli/commands/knowledge/ls.ts
47079
48128
  function registerKnowledgeLs(program3) {
47080
48129
  program3.command("knowledge:ls <path>").description(
47081
- "List knowledge nodes for a Knowledge Map path\n Examples:\n elevasis-sdk knowledge:ls /by-kind/playbook\n elevasis-sdk knowledge:ls /by-system/sales.crm\n elevasis-sdk knowledge:ls /by-owner/role.ops-lead\n elevasis-sdk knowledge:ls /graph/knowledge.outreach-playbook/governs\n elevasis-sdk knowledge:ls /graph/system:sales.crm/governed-by"
48130
+ "List knowledge nodes for a Knowledge Map path\n Examples:\n elevasis-sdk knowledge:ls /by-kind/playbook\n elevasis-sdk knowledge:ls /by-system/sales.crm\n elevasis-sdk knowledge:ls /by-ontology/sales.crm:object/deal\n elevasis-sdk knowledge:ls /by-owner/role.ops-lead\n elevasis-sdk knowledge:ls /graph/knowledge.outreach-playbook/governs\n elevasis-sdk knowledge:ls /graph/system:sales.crm/governed-by"
47082
48131
  ).option("--json", "Print wrapped JSON envelope { path, mount, args, results }").option("--ids-only", "Print one ID per line (for piping)").action(
47083
48132
  wrapAction("knowledge:ls", async (pathArg, options) => {
47084
48133
  let parsed;
@@ -47094,12 +48143,18 @@ function registerKnowledgeLs(program3) {
47094
48143
  const graph = buildOrganizationGraph({ organizationModel: model });
47095
48144
  const knowledgeNodes = Object.values(model.knowledge);
47096
48145
  let results;
48146
+ let isGraphMount = false;
47097
48147
  switch (parsed.mount) {
47098
48148
  case "by-system": {
47099
48149
  const systemId = parsed.args[0].replace(/\//g, ".");
47100
48150
  results = bySystem(graph, systemId, knowledgeNodes);
47101
48151
  break;
47102
48152
  }
48153
+ case "by-ontology": {
48154
+ const ontologyId = parsed.args[0];
48155
+ results = byOntology(graph, ontologyId, knowledgeNodes);
48156
+ break;
48157
+ }
47103
48158
  case "by-kind": {
47104
48159
  const kind = parsed.args[0];
47105
48160
  results = byKind(graph, kind, knowledgeNodes);
@@ -47111,6 +48166,7 @@ function registerKnowledgeLs(program3) {
47111
48166
  break;
47112
48167
  }
47113
48168
  case "graph": {
48169
+ isGraphMount = true;
47114
48170
  const nodeId2 = parsed.args[0];
47115
48171
  const verb = parsed.args[1];
47116
48172
  if (verb === "governs") {
@@ -47135,6 +48191,12 @@ function registerKnowledgeLs(program3) {
47135
48191
  } else if (options.idsOnly) {
47136
48192
  const out = formatIdsOnly(results);
47137
48193
  if (out) process.stdout.write(out + "\n");
48194
+ } else if (isGraphMount) {
48195
+ if (results.length === 0) {
48196
+ process.stdout.write("(no results)\n");
48197
+ } else {
48198
+ process.stdout.write(results.join("\n") + "\n");
48199
+ }
47138
48200
  } else {
47139
48201
  process.stdout.write(formatText(results) + "\n");
47140
48202
  }
@@ -47157,22 +48219,7 @@ function registerKnowledgeCat(program3) {
47157
48219
  process.exit(1);
47158
48220
  }
47159
48221
  if (options.json) {
47160
- process.stdout.write(
47161
- JSON.stringify(
47162
- {
47163
- id: node.id,
47164
- kind: node.kind,
47165
- title: node.title,
47166
- summary: node.summary,
47167
- body: node.body,
47168
- links: node.links,
47169
- ownerIds: node.ownerIds,
47170
- updatedAt: node.updatedAt
47171
- },
47172
- null,
47173
- 2
47174
- ) + "\n"
47175
- );
48222
+ process.stdout.write(JSON.stringify(node, null, 2) + "\n");
47176
48223
  } else {
47177
48224
  process.stdout.write(node.body + "\n");
47178
48225
  }
@@ -47190,7 +48237,8 @@ function registerKnowledgeGraph(program3) {
47190
48237
  const model = await loadOrgModel(projectRoot);
47191
48238
  const graph = buildOrganizationGraph({ organizationModel: model });
47192
48239
  const outgoing = governs(graph, id);
47193
- const incoming = governedBy(graph, id);
48240
+ const incomingNodeId = id.startsWith("knowledge.") ? `knowledge:${id}` : id;
48241
+ const incoming = governedBy(graph, incomingNodeId);
47194
48242
  if (options.json) {
47195
48243
  process.stdout.write(
47196
48244
  JSON.stringify(
@@ -47495,6 +48543,18 @@ var ROUTING_STOPWORDS = /* @__PURE__ */ new Set([
47495
48543
  function toRegistryPath(path3) {
47496
48544
  return path3.replace(/\\/g, "/");
47497
48545
  }
48546
+ function sourceBaseFromLabel(sourceLabel) {
48547
+ if (!sourceLabel) return void 0;
48548
+ const normalized = toRegistryPath(sourceLabel).replace(/\/+$/, "");
48549
+ const globIndex = normalized.indexOf("*");
48550
+ if (globIndex === -1) return normalized;
48551
+ return normalized.slice(0, globIndex).replace(/\/+$/, "");
48552
+ }
48553
+ function toSourceFilePath(sourceLabel, relativePath) {
48554
+ const normalizedRelativePath = toRegistryPath(relativePath);
48555
+ const sourceBase = sourceBaseFromLabel(sourceLabel);
48556
+ return sourceBase ? `${sourceBase}/${normalizedRelativePath}` : normalizedRelativePath;
48557
+ }
47498
48558
  function slugify(value) {
47499
48559
  return value.trim().toLowerCase().replace(/['"]/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
47500
48560
  }
@@ -47658,7 +48718,13 @@ function generateKnowledgeNodes(options) {
47658
48718
  const files = listMdxFiles(options.sourceDir).sort(
47659
48719
  (a, b) => (0, import_node_path2.relative)(options.sourceDir, a).localeCompare((0, import_node_path2.relative)(options.sourceDir, b))
47660
48720
  );
47661
- const nodes = files.map(readKnowledgeNodeMdx);
48721
+ const nodes = files.map((file2) => {
48722
+ const relativePath = (0, import_node_path2.relative)(options.sourceDir, file2);
48723
+ return {
48724
+ ...readKnowledgeNodeMdx(file2),
48725
+ sourceFilePath: toSourceFilePath(options.sourceLabel, relativePath)
48726
+ };
48727
+ });
47662
48728
  const sourcePaths = Object.fromEntries(
47663
48729
  files.map((file2, index) => [nodes[index].id, toRegistryPath((0, import_node_path2.relative)(options.sourceDir, file2))])
47664
48730
  );