@elevasis/core 0.22.0 → 0.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/dist/index.d.ts +2330 -2391
  2. package/dist/index.js +2322 -1147
  3. package/dist/knowledge/index.d.ts +702 -1136
  4. package/dist/knowledge/index.js +9 -9
  5. package/dist/organization-model/index.d.ts +2330 -2391
  6. package/dist/organization-model/index.js +2322 -1147
  7. package/dist/test-utils/index.d.ts +703 -1106
  8. package/dist/test-utils/index.js +1735 -1089
  9. package/package.json +1 -1
  10. package/src/__tests__/template-core-compatibility.test.ts +11 -79
  11. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +360 -98
  12. package/src/business/acquisition/api-schemas.test.ts +2 -2
  13. package/src/business/acquisition/api-schemas.ts +7 -9
  14. package/src/business/acquisition/build-templates.test.ts +4 -4
  15. package/src/business/acquisition/build-templates.ts +72 -30
  16. package/src/business/acquisition/crm-state-actions.test.ts +13 -11
  17. package/src/business/acquisition/types.ts +7 -3
  18. package/src/execution/engine/agent/core/types.ts +1 -1
  19. package/src/execution/engine/workflow/types.ts +2 -2
  20. package/src/knowledge/README.md +8 -7
  21. package/src/knowledge/__tests__/queries.test.ts +74 -73
  22. package/src/knowledge/format.ts +10 -9
  23. package/src/knowledge/index.ts +1 -1
  24. package/src/knowledge/published.ts +1 -1
  25. package/src/knowledge/queries.ts +26 -25
  26. package/src/organization-model/README.md +66 -26
  27. package/src/organization-model/__tests__/content-kinds-registry.test.ts +210 -0
  28. package/src/organization-model/__tests__/defaults.test.ts +72 -98
  29. package/src/organization-model/__tests__/domains/actions.test.ts +56 -0
  30. package/src/organization-model/__tests__/domains/customers.test.ts +299 -295
  31. package/src/organization-model/__tests__/domains/entities.test.ts +56 -0
  32. package/src/organization-model/__tests__/domains/goals.test.ts +493 -479
  33. package/src/organization-model/__tests__/domains/identity.test.ts +280 -279
  34. package/src/organization-model/__tests__/domains/navigation.test.ts +268 -212
  35. package/src/organization-model/__tests__/domains/offerings.test.ts +414 -419
  36. package/src/organization-model/__tests__/domains/policies.test.ts +323 -0
  37. package/src/organization-model/__tests__/domains/resource-mappings.test.ts +271 -271
  38. package/src/organization-model/__tests__/domains/resources.test.ts +159 -37
  39. package/src/organization-model/__tests__/domains/roles.test.ts +147 -86
  40. package/src/organization-model/__tests__/domains/statuses.test.ts +246 -243
  41. package/src/organization-model/__tests__/domains/systems.test.ts +67 -51
  42. package/src/organization-model/__tests__/flatten-additive-merge.test.ts +361 -0
  43. package/src/organization-model/__tests__/foundation.test.ts +74 -102
  44. package/src/organization-model/__tests__/get-resources-for-system.test.ts +144 -0
  45. package/src/organization-model/__tests__/graph.test.ts +899 -71
  46. package/src/organization-model/__tests__/knowledge.test.ts +173 -52
  47. package/src/organization-model/__tests__/lookup-helpers.test.ts +438 -0
  48. package/src/organization-model/__tests__/migration-helpers.test.ts +591 -0
  49. package/src/organization-model/__tests__/prospecting-ssot.test.ts +36 -27
  50. package/src/organization-model/__tests__/recursive-system-schema.test.ts +520 -0
  51. package/src/organization-model/__tests__/resolve.test.ts +174 -23
  52. package/src/organization-model/__tests__/schema.test.ts +291 -114
  53. package/src/organization-model/__tests__/surface-projection.test.ts +207 -97
  54. package/src/organization-model/catalogs/lead-gen.ts +144 -0
  55. package/src/organization-model/content-kinds/config.ts +36 -0
  56. package/src/organization-model/content-kinds/index.ts +74 -0
  57. package/src/organization-model/content-kinds/pipeline.ts +68 -0
  58. package/src/organization-model/content-kinds/registry.ts +44 -0
  59. package/src/organization-model/content-kinds/status.ts +71 -0
  60. package/src/organization-model/content-kinds/template.ts +83 -0
  61. package/src/organization-model/content-kinds/types.ts +117 -0
  62. package/src/organization-model/contracts.ts +13 -3
  63. package/src/organization-model/defaults.ts +488 -96
  64. package/src/organization-model/domains/actions.ts +239 -0
  65. package/src/organization-model/domains/customers.ts +78 -75
  66. package/src/organization-model/domains/entities.ts +144 -0
  67. package/src/organization-model/domains/goals.ts +83 -80
  68. package/src/organization-model/domains/knowledge.ts +74 -16
  69. package/src/organization-model/domains/navigation.ts +107 -384
  70. package/src/organization-model/domains/offerings.ts +71 -66
  71. package/src/organization-model/domains/policies.ts +102 -0
  72. package/src/organization-model/domains/projects.ts +14 -48
  73. package/src/organization-model/domains/prospecting.ts +62 -181
  74. package/src/organization-model/domains/resources.ts +81 -24
  75. package/src/organization-model/domains/roles.ts +13 -10
  76. package/src/organization-model/domains/sales.ts +10 -219
  77. package/src/organization-model/domains/shared.ts +57 -57
  78. package/src/organization-model/domains/statuses.ts +339 -130
  79. package/src/organization-model/domains/systems.ts +186 -29
  80. package/src/organization-model/foundation.ts +54 -67
  81. package/src/organization-model/graph/build.ts +682 -54
  82. package/src/organization-model/graph/link.ts +1 -1
  83. package/src/organization-model/graph/schema.ts +24 -9
  84. package/src/organization-model/graph/types.ts +20 -7
  85. package/src/organization-model/helpers.ts +231 -26
  86. package/src/organization-model/index.ts +116 -5
  87. package/src/organization-model/migration-helpers.ts +249 -0
  88. package/src/organization-model/organization-graph.mdx +16 -15
  89. package/src/organization-model/organization-model.mdx +89 -41
  90. package/src/organization-model/published.ts +120 -18
  91. package/src/organization-model/resolve.ts +117 -54
  92. package/src/organization-model/schema.ts +561 -140
  93. package/src/organization-model/surface-projection.ts +116 -122
  94. package/src/organization-model/types.ts +102 -21
  95. package/src/platform/constants/versions.ts +1 -1
  96. package/src/platform/registry/__tests__/command-view.test.ts +6 -8
  97. package/src/platform/registry/__tests__/resource-link.test.ts +13 -8
  98. package/src/platform/registry/__tests__/resource-registry.integration.test.ts +16 -31
  99. package/src/platform/registry/__tests__/resource-registry.nested-systems.test.ts +245 -0
  100. package/src/platform/registry/__tests__/resource-registry.test.ts +9 -7
  101. package/src/platform/registry/__tests__/validation.test.ts +15 -11
  102. package/src/platform/registry/resource-registry.ts +20 -8
  103. package/src/platform/registry/serialization.ts +7 -7
  104. package/src/platform/registry/types.ts +3 -3
  105. package/src/platform/registry/validation.ts +17 -15
  106. package/src/reference/_generated/contracts.md +362 -99
  107. package/src/reference/glossary.md +18 -18
  108. package/src/supabase/database.types.ts +60 -0
  109. package/src/test-utils/test-utils.test.ts +1 -6
  110. package/src/organization-model/__tests__/domains/operations.test.ts +0 -203
  111. package/src/organization-model/domains/features.ts +0 -31
  112. package/src/organization-model/domains/operations.ts +0 -85
@@ -1,80 +1,83 @@
1
- import { z } from 'zod'
2
-
3
- // ---------------------------------------------------------------------------
4
- // Measurable outcome schema — one trackable result that supports a goal.
5
- // The field name `keyResults` is used for compatibility with OKR tooling;
6
- // user-facing surfaces and documentation MUST say "measurable outcomes",
7
- // never "key results" or "OKR".
8
- // ---------------------------------------------------------------------------
9
-
10
- export const KeyResultSchema = z.object({
11
- /** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
12
- id: z.string().trim().min(1).max(100),
13
- /** Plain-language description of this measurable outcome (e.g. "Increase trial-to-paid conversion"). */
14
- description: z.string().trim().min(1).max(500),
15
- /**
16
- * What is being measured — the metric name (e.g. "monthly revenue", "NPS score",
17
- * "trial-to-paid conversion rate"). Free-form string.
18
- */
19
- targetMetric: z.string().trim().min(1).max(200),
20
- /** Current measured value. Defaults to 0 when not yet tracked. */
21
- currentValue: z.number().default(0),
22
- /**
23
- * Target value to reach for this measurable outcome to be considered achieved.
24
- * Optional — omit if the outcome is directional (e.g. "reduce churn") without
25
- * a hard numeric target.
26
- */
27
- targetValue: z.number().optional()
28
- })
29
-
30
- // ---------------------------------------------------------------------------
31
- // Objective schema — one goal the organization is working toward.
32
- // User-facing label is "goal"; this schema type is named Objective for
33
- // structural continuity with OKR tooling. Do NOT expose "OKR", "objective",
34
- // or "key result" in any user-facing label or documentation.
35
- //
36
- // Period fields use ISO 8601 date strings (YYYY-MM-DD). Cross-schema
37
- // validation (periodEnd > periodStart) is enforced in
38
- // `OrganizationModelSchema.superRefine()`.
39
- // ---------------------------------------------------------------------------
40
-
41
- const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
42
-
43
- export const ObjectiveSchema = z.object({
44
- /** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
45
- id: z.string().trim().min(1).max(100),
46
- /** Plain-language description of what the organization wants to achieve. */
47
- description: z.string().trim().min(1).max(1000),
48
- /**
49
- * Start of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
50
- * Must be strictly before `periodEnd`.
51
- */
52
- periodStart: z.string().regex(ISO_DATE_REGEX, 'periodStart must be an ISO date string (YYYY-MM-DD)'),
53
- /**
54
- * End of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
55
- * Must be strictly after `periodStart`.
56
- * Enforced via `OrganizationModelSchema.superRefine()`.
57
- */
58
- periodEnd: z.string().regex(ISO_DATE_REGEX, 'periodEnd must be an ISO date string (YYYY-MM-DD)'),
59
- /**
60
- * List of measurable outcomes that define success for this goal.
61
- * Defaults to empty array so goals can be declared before outcomes are defined.
62
- */
63
- keyResults: z.array(KeyResultSchema).default([])
64
- })
65
-
66
- // ---------------------------------------------------------------------------
67
- // Goals domain schema — a collection of goals the organization is pursuing.
68
- // ---------------------------------------------------------------------------
69
-
70
- export const GoalsDomainSchema = z.object({
71
- objectives: z.array(ObjectiveSchema).default([])
72
- })
73
-
74
- // ---------------------------------------------------------------------------
75
- // Seed empty by default; adapters populate with real goal definitions.
76
- // ---------------------------------------------------------------------------
77
-
78
- export const DEFAULT_ORGANIZATION_MODEL_GOALS: z.infer<typeof GoalsDomainSchema> = {
79
- objectives: []
80
- }
1
+ import { z } from 'zod'
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Measurable outcome schema — one trackable result that supports a goal.
5
+ // The field name `keyResults` is used for compatibility with OKR tooling;
6
+ // user-facing surfaces and documentation MUST say "measurable outcomes",
7
+ // never "key results" or "OKR".
8
+ // ---------------------------------------------------------------------------
9
+
10
+ export const KeyResultSchema = z.object({
11
+ /** Stable unique identifier for the measurable outcome (e.g. "kr-revenue-q1"). */
12
+ id: z.string().trim().min(1).max(100),
13
+ /** Plain-language description of this measurable outcome (e.g. "Increase trial-to-paid conversion"). */
14
+ description: z.string().trim().min(1).max(500),
15
+ /**
16
+ * What is being measured — the metric name (e.g. "monthly revenue", "NPS score",
17
+ * "trial-to-paid conversion rate"). Free-form string.
18
+ */
19
+ targetMetric: z.string().trim().min(1).max(200),
20
+ /** Current measured value. Defaults to 0 when not yet tracked. */
21
+ currentValue: z.number().default(0),
22
+ /**
23
+ * Target value to reach for this measurable outcome to be considered achieved.
24
+ * Optional — omit if the outcome is directional (e.g. "reduce churn") without
25
+ * a hard numeric target.
26
+ */
27
+ targetValue: z.number().optional()
28
+ })
29
+
30
+ // ---------------------------------------------------------------------------
31
+ // Objective schema — one goal the organization is working toward.
32
+ // User-facing label is "goal"; this schema type is named Objective for
33
+ // structural continuity with OKR tooling. Do NOT expose "OKR", "objective",
34
+ // or "key result" in any user-facing label or documentation.
35
+ //
36
+ // Period fields use ISO 8601 date strings (YYYY-MM-DD). Cross-schema
37
+ // validation (periodEnd > periodStart) is enforced in
38
+ // `OrganizationModelSchema.superRefine()`.
39
+ // ---------------------------------------------------------------------------
40
+
41
+ const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}$/
42
+
43
+ export const ObjectiveSchema = z.object({
44
+ /** Stable unique identifier for the goal (e.g. "goal-grow-arr-q1-2026"). */
45
+ id: z.string().trim().min(1).max(100),
46
+ /** Domain-map iteration order. Convention: multiples of 10 (10, 20, 30, ...) to allow easy insertion. */
47
+ order: z.number(),
48
+ /** Plain-language description of what the organization wants to achieve. */
49
+ description: z.string().trim().min(1).max(1000),
50
+ /**
51
+ * Start of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
52
+ * Must be strictly before `periodEnd`.
53
+ */
54
+ periodStart: z.string().regex(ISO_DATE_REGEX, 'periodStart must be an ISO date string (YYYY-MM-DD)'),
55
+ /**
56
+ * End of the period this goal is active for — ISO 8601 date string (YYYY-MM-DD).
57
+ * Must be strictly after `periodStart`.
58
+ * Enforced via `OrganizationModelSchema.superRefine()`.
59
+ */
60
+ periodEnd: z.string().regex(ISO_DATE_REGEX, 'periodEnd must be an ISO date string (YYYY-MM-DD)'),
61
+ /**
62
+ * List of measurable outcomes that define success for this goal.
63
+ * Defaults to empty array so goals can be declared before outcomes are defined.
64
+ */
65
+ keyResults: z.array(KeyResultSchema).default([])
66
+ })
67
+
68
+ // ---------------------------------------------------------------------------
69
+ // Goals domain schema — a collection of goals the organization is pursuing.
70
+ // ---------------------------------------------------------------------------
71
+
72
+ export const GoalsDomainSchema = z
73
+ .record(z.string(), ObjectiveSchema)
74
+ .refine((record) => Object.entries(record).every(([key, entry]) => entry.id === key), {
75
+ message: 'Each objective entry id must match its map key'
76
+ })
77
+ .default({})
78
+
79
+ // ---------------------------------------------------------------------------
80
+ // Seed — empty by default; adapters populate with real goal definitions.
81
+ // ---------------------------------------------------------------------------
82
+
83
+ export const DEFAULT_ORGANIZATION_MODEL_GOALS: z.infer<typeof GoalsDomainSchema> = {}
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod'
2
2
  import { IconNameSchema, ModelIdSchema } from './shared'
3
- import { NodeIdStringSchema } from './features'
3
+ import { NodeIdStringSchema } from './systems'
4
4
  import { RoleIdSchema } from './roles'
5
5
 
6
6
  // ---------------------------------------------------------------------------
@@ -9,12 +9,60 @@ import { RoleIdSchema } from './roles'
9
9
  // Phase 1 only emits 'governs' edges from knowledge nodes.
10
10
  // ---------------------------------------------------------------------------
11
11
 
12
- export const KnowledgeLinkSchema = z.object({
12
+ export const KnowledgeTargetKindSchema = z
13
+ .enum([
14
+ 'system',
15
+ 'resource',
16
+ 'knowledge',
17
+ 'stage',
18
+ 'action',
19
+ 'role',
20
+ 'goal',
21
+ 'customer-segment',
22
+ 'offering',
23
+ // D4: content nodes are a valid knowledge target after compound-domain data moved into system.content
24
+ 'content-node'
25
+ ])
26
+ .meta({ label: 'Target kind' })
27
+
28
+ export const KnowledgeTargetRefSchema = z.object({
29
+ kind: KnowledgeTargetKindSchema,
30
+ // D4: content-node targets use a qualified id format '<system-path>:<local-content-id>'
31
+ // which contains a colon separator and cannot satisfy ModelIdSchema. Use a permissive
32
+ // string schema here; business-logic validation of target existence is done in
33
+ // OrganizationModelSchema.superRefine (knowledgeTargetExists).
34
+ id: z.string().trim().min(1).max(300)
35
+ })
36
+
37
+ const LegacyKnowledgeLinkSchema = z.object({
13
38
  nodeId: NodeIdStringSchema
14
39
  })
15
40
 
16
- export const KnowledgeSkillBindingSchema = z.string().trim().min(1).max(120)
17
- export const KnowledgeDomainBindingSchema = z.string().trim().min(1).max(80)
41
+ const CanonicalKnowledgeLinkSchema = z.object({
42
+ target: KnowledgeTargetRefSchema
43
+ })
44
+
45
+ function nodeIdFromTarget(target: z.infer<typeof KnowledgeTargetRefSchema>): string {
46
+ return `${target.kind}:${target.id}`
47
+ }
48
+
49
+ function targetFromNodeId(nodeId: string): z.infer<typeof KnowledgeTargetRefSchema> {
50
+ const [kind, ...idParts] = nodeId.split(':')
51
+ return {
52
+ kind: KnowledgeTargetKindSchema.parse(kind),
53
+ id: idParts.join(':')
54
+ }
55
+ }
56
+
57
+ export const KnowledgeLinkSchema = z
58
+ .union([CanonicalKnowledgeLinkSchema, LegacyKnowledgeLinkSchema])
59
+ .transform((link) => {
60
+ const target = 'target' in link ? link.target : targetFromNodeId(link.nodeId)
61
+ return {
62
+ target,
63
+ nodeId: nodeIdFromTarget(target)
64
+ }
65
+ })
18
66
 
19
67
  // ---------------------------------------------------------------------------
20
68
  // OrgKnowledgeNode — single schema, `kind` discriminator drives presentation.
@@ -22,7 +70,9 @@ export const KnowledgeDomainBindingSchema = z.string().trim().min(1).max(80)
22
70
  // Phase 2 (deferred): structured block format (Supabase-backed authoring).
23
71
  // ---------------------------------------------------------------------------
24
72
 
25
- export const OrgKnowledgeKindSchema = z.enum(['playbook', 'strategy', 'reference'])
73
+ export const OrgKnowledgeKindSchema = z
74
+ .enum(['playbook', 'strategy', 'reference'])
75
+ .meta({ label: 'Knowledge kind', color: 'grape' })
26
76
 
27
77
  export const OrgKnowledgeNodeSchema = z.object({
28
78
  id: ModelIdSchema,
@@ -30,6 +80,8 @@ export const OrgKnowledgeNodeSchema = z.object({
30
80
  title: z.string().trim().min(1).max(200),
31
81
  summary: z.string().trim().min(1).max(1000),
32
82
  icon: IconNameSchema.optional(),
83
+ /** Canonical documentation URL when body content is a local summary. */
84
+ externalUrl: z.string().trim().url().max(500).optional(),
33
85
  /** Raw MDX string. Phase 2 will introduce a structured block format. */
34
86
  body: z.string().trim().min(1),
35
87
  /**
@@ -37,27 +89,33 @@ export const OrgKnowledgeNodeSchema = z.object({
37
89
  * Each link emits a `governs` edge: knowledge-node -> target node.
38
90
  */
39
91
  links: z.array(KnowledgeLinkSchema).default([]),
40
- /** Operator skill or command bindings relevant to this node. */
41
- skills: z.array(KnowledgeSkillBindingSchema).optional(),
42
- /** Domain key used to derive fast graph->skill registries. */
43
- domain: KnowledgeDomainBindingSchema.optional(),
44
92
  /** Role identifiers that own this knowledge node. */
45
- ownerIds: z.array(RoleIdSchema).default([]),
93
+ ownerIds: z.array(RoleIdSchema.meta({ ref: 'role' })).default([]),
46
94
  /** ISO date string (YYYY-MM-DD or full ISO 8601) of last meaningful update. */
47
95
  updatedAt: z.string().trim().min(1).max(50)
48
96
  })
49
97
 
50
98
  // ---------------------------------------------------------------------------
51
- // Domain schema — flat array of knowledge nodes
99
+ // Domain schema — flat Record<id, KnowledgeNode> (D3: flatten per Phase 4 cut)
100
+ //
101
+ // Wave 1 shape change: the old wrapper object { version, lastModified, nodes[] }
102
+ // is replaced by a plain id-keyed map. version/lastModified move to
103
+ // domainMetadata.knowledge (D7). The default is an empty map {}.
104
+ //
105
+ // Wave 2 (elevasis-core canonicalOrganizationModel) must produce a value of this
106
+ // shape: Record<KnowledgeId, OrgKnowledgeNode> — i.e., an object keyed by
107
+ // each node's id string, with OrgKnowledgeNode as the value. Example:
108
+ // knowledge: {
109
+ // 'playbook.crm.discovery': { id: 'playbook.crm.discovery', kind: 'playbook', ... },
110
+ // }
52
111
  // ---------------------------------------------------------------------------
53
112
 
54
- export const KnowledgeDomainSchema = z.object({
55
- nodes: z.array(OrgKnowledgeNodeSchema).default([])
56
- })
113
+ export const KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({})
57
114
 
58
115
  export type OrgKnowledgeNode = z.infer<typeof OrgKnowledgeNodeSchema>
116
+ export type OrgKnowledgeNodeInput = z.input<typeof OrgKnowledgeNodeSchema>
59
117
  export type OrgKnowledgeKind = z.infer<typeof OrgKnowledgeKindSchema>
118
+ export type KnowledgeTargetKind = z.infer<typeof KnowledgeTargetKindSchema>
119
+ export type KnowledgeTargetRef = z.infer<typeof KnowledgeTargetRefSchema>
60
120
  export type KnowledgeLink = z.infer<typeof KnowledgeLinkSchema>
61
- export type KnowledgeSkillBinding = z.infer<typeof KnowledgeSkillBindingSchema>
62
- export type KnowledgeDomainBinding = z.infer<typeof KnowledgeDomainBindingSchema>
63
121
  export type KnowledgeDomain = z.infer<typeof KnowledgeDomainSchema>