@elevasis/core 0.24.0 → 0.25.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 (50) hide show
  1. package/dist/index.d.ts +3117 -2166
  2. package/dist/index.js +574 -16
  3. package/dist/knowledge/index.d.ts +122 -7
  4. package/dist/organization-model/index.d.ts +3117 -2166
  5. package/dist/organization-model/index.js +574 -16
  6. package/dist/test-utils/index.d.ts +135 -45
  7. package/dist/test-utils/index.js +122 -14
  8. package/package.json +3 -3
  9. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +139 -101
  10. package/src/execution/engine/llm/adapters/__tests__/openrouter.integration.test.ts +10 -10
  11. package/src/execution/engine/workflow/types.ts +5 -7
  12. package/src/knowledge/__tests__/queries.test.ts +960 -546
  13. package/src/knowledge/format.ts +322 -100
  14. package/src/knowledge/index.ts +18 -5
  15. package/src/knowledge/queries.ts +1004 -239
  16. package/src/organization-model/__tests__/deprecate-helpers.test.ts +71 -0
  17. package/src/organization-model/__tests__/domains/resources.test.ts +19 -8
  18. package/src/organization-model/__tests__/domains/topology.test.ts +188 -0
  19. package/src/organization-model/__tests__/graph.test.ts +98 -7
  20. package/src/organization-model/__tests__/resolve.test.ts +9 -7
  21. package/src/organization-model/__tests__/scaffolders.test.ts +93 -0
  22. package/src/organization-model/__tests__/schema.test.ts +14 -4
  23. package/src/organization-model/defaults.ts +5 -3
  24. package/src/organization-model/domains/resources.ts +63 -20
  25. package/src/organization-model/domains/topology.ts +261 -0
  26. package/src/organization-model/graph/build.ts +63 -15
  27. package/src/organization-model/graph/schema.ts +4 -3
  28. package/src/organization-model/graph/types.ts +5 -4
  29. package/src/organization-model/helpers.ts +76 -9
  30. package/src/organization-model/icons.ts +1 -0
  31. package/src/organization-model/index.ts +7 -5
  32. package/src/organization-model/ontology.ts +2 -5
  33. package/src/organization-model/organization-model.mdx +16 -11
  34. package/src/organization-model/published.ts +51 -15
  35. package/src/organization-model/scaffolders/helpers.ts +84 -0
  36. package/src/organization-model/scaffolders/index.ts +19 -0
  37. package/src/organization-model/scaffolders/scaffoldKnowledgeNode.ts +48 -0
  38. package/src/organization-model/scaffolders/scaffoldOntologyRecord.ts +38 -0
  39. package/src/organization-model/scaffolders/scaffoldResource.ts +59 -0
  40. package/src/organization-model/scaffolders/scaffoldSystem.ts +110 -0
  41. package/src/organization-model/scaffolders/types.ts +81 -0
  42. package/src/organization-model/schema.ts +51 -11
  43. package/src/organization-model/types.ts +25 -11
  44. package/src/platform/constants/versions.ts +1 -1
  45. package/src/platform/registry/__tests__/validation.test.ts +199 -14
  46. package/src/platform/registry/resource-registry.ts +11 -11
  47. package/src/platform/registry/validation.ts +226 -34
  48. package/src/reference/_generated/contracts.md +139 -101
  49. package/src/reference/glossary.md +74 -72
  50. package/src/supabase/database.types.ts +3156 -3153
@@ -135,17 +135,22 @@ Resource identity is authored in the OM Resources domain. Operations imports des
135
135
  ```ts
136
136
  import { defineResources } from '@elevasis/core/organization-model'
137
137
 
138
- export const resourceDescriptors = defineResources({
139
- leadImport: {
140
- id: 'lgn-01c-apollo-import-workflow',
141
- kind: 'workflow',
142
- systemPath: 'sales.lead-gen',
143
- ownerRoleId: 'role-ops-lead',
144
- status: 'active',
145
- actionKey: 'lead-gen.company.apollo-import',
146
- codeRefs: [
147
- {
148
- path: 'packages/elevasis-operations/src/sales/prospecting/scrape/apollo-import.ts',
138
+ export const resourceDescriptors = defineResources({
139
+ leadImport: {
140
+ id: 'lgn-01c-apollo-import-workflow',
141
+ title: 'Apollo Import',
142
+ description: 'Imports Apollo company records into the lead generation pipeline.',
143
+ kind: 'workflow',
144
+ systemPath: 'sales.lead-gen',
145
+ ownerRoleId: 'role-ops-lead',
146
+ status: 'active',
147
+ ontology: {
148
+ actions: ['sales.lead-gen:action/company.apollo-import'],
149
+ primaryAction: 'sales.lead-gen:action/company.apollo-import'
150
+ },
151
+ codeRefs: [
152
+ {
153
+ path: 'packages/elevasis-operations/src/sales/prospecting/scrape/apollo-import.ts',
149
154
  role: 'entrypoint',
150
155
  symbol: 'lgnApolloImportWorkflow'
151
156
  }
@@ -107,10 +107,11 @@ export {
107
107
  AgentKindSchema,
108
108
  AgentResourceEntrySchema,
109
109
  CodeReferenceRoleSchema,
110
- CodeReferenceSchema,
111
- DEFAULT_ORGANIZATION_MODEL_RESOURCES,
112
- defineResource,
113
- defineResources,
110
+ CodeReferenceSchema,
111
+ DEFAULT_ORGANIZATION_MODEL_RESOURCES,
112
+ defineResource,
113
+ defineResourceOntology,
114
+ defineResources,
114
115
  EventDescriptorSchema,
115
116
  EventEmissionDescriptorSchema,
116
117
  EventIdSchema,
@@ -121,11 +122,27 @@ export {
121
122
  ResourceKindSchema,
122
123
  ResourceOntologyBindingSchema,
123
124
  ResourcesDomainSchema,
124
- ScriptResourceEntrySchema,
125
- ScriptResourceLanguageSchema,
126
- ScriptResourceSourceSchema,
127
- WorkflowResourceEntrySchema
128
- } from './domains/resources'
125
+ ScriptResourceEntrySchema,
126
+ ScriptResourceLanguageSchema,
127
+ ScriptResourceSourceSchema,
128
+ WorkflowResourceEntrySchema
129
+ } from './domains/resources'
130
+ export {
131
+ compileTopologyNodeRef,
132
+ DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
133
+ defineTopology,
134
+ defineTopologyRelationship,
135
+ isOntologyTopologyRef,
136
+ OmTopologyDomainSchema,
137
+ OmTopologyMetadataSchema,
138
+ OmTopologyNodeKindSchema,
139
+ OmTopologyNodeRefSchema,
140
+ OmTopologyRelationshipKindSchema,
141
+ OmTopologyRelationshipSchema,
142
+ parseTopologyNodeRef,
143
+ topologyRelationship,
144
+ topologyRef
145
+ } from './domains/topology'
129
146
  export {
130
147
  ActionsDomainSchema,
131
148
  ActionIdSchema,
@@ -184,8 +201,21 @@ export {
184
201
  } from './domains/knowledge'
185
202
  export { defineOrganizationModel, resolveOrganizationModel, resolveOrganizationModelWithResources } from './resolve'
186
203
  export type { ResolvedSystemEntry, ResolvedOrganizationModel } from './resolve'
187
- export { createFoundationOrganizationModel } from './foundation'
188
-
204
+ export { createFoundationOrganizationModel } from './foundation'
205
+ export { scaffoldOrganizationModel } from './scaffolders'
206
+ export type {
207
+ BaseOmScaffoldSpec,
208
+ KnowledgeNodeScaffoldSpec,
209
+ OmScaffoldEdit,
210
+ OmScaffoldIntent,
211
+ OmScaffoldPlan,
212
+ OmScaffoldSpec,
213
+ OmScaffoldWrite,
214
+ OntologyRecordScaffoldSpec,
215
+ ResourceScaffoldSpec,
216
+ SystemScaffoldSpec
217
+ } from './scaffolders'
218
+
189
219
  export type {
190
220
  OntologyActionType,
191
221
  OntologyCatalogType,
@@ -249,10 +279,16 @@ export type {
249
279
  OrganizationModelResourceKind,
250
280
  OrganizationModelResourceOntologyBinding,
251
281
  OrganizationModelResources,
252
- OrganizationModelScriptResourceEntry,
253
- OrganizationModelScriptResourceLanguage,
254
- OrganizationModelScriptResourceSource,
255
- OrganizationModelWorkflowResourceEntry,
282
+ OrganizationModelScriptResourceEntry,
283
+ OrganizationModelScriptResourceLanguage,
284
+ OrganizationModelScriptResourceSource,
285
+ OrganizationModelTopology,
286
+ OrganizationModelTopologyMetadata,
287
+ OrganizationModelTopologyNodeKind,
288
+ OrganizationModelTopologyNodeRef,
289
+ OrganizationModelTopologyRelationship,
290
+ OrganizationModelTopologyRelationshipKind,
291
+ OrganizationModelWorkflowResourceEntry,
256
292
  OrganizationModelActions,
257
293
  OrganizationModelAction,
258
294
  OrganizationModelActionId,
@@ -0,0 +1,84 @@
1
+ import { formatOntologyId, type OntologyKind, type OrganizationModel } from '..'
2
+ import { getSystem, listAllSystems } from '../helpers'
3
+ import type { OmScaffoldPlan } from './types'
4
+
5
+ export function slugify(input: string): string {
6
+ return input
7
+ .trim()
8
+ .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
9
+ .toLowerCase()
10
+ .replace(/[^a-z0-9]+/g, '-')
11
+ .replace(/^-+|-+$/g, '')
12
+ }
13
+
14
+ export function titleize(input: string): string {
15
+ return input
16
+ .split(/[-._\s]+/)
17
+ .filter(Boolean)
18
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
19
+ .join(' ')
20
+ }
21
+
22
+ export function assertSystemPathAvailable(model: OrganizationModel, path: string): void {
23
+ if (getSystem(model, path) !== undefined) {
24
+ throw new Error(`system already exists: ${path}`)
25
+ }
26
+
27
+ const parent = parentPathOf(path)
28
+ if (parent !== undefined && getSystem(model, parent) === undefined) {
29
+ throw new Error(`parent system does not exist: ${parent}`)
30
+ }
31
+ }
32
+
33
+ export function assertSystemExists(model: OrganizationModel, path: string): void {
34
+ if (getSystem(model, path) === undefined) {
35
+ throw new Error(`system does not exist: ${path}`)
36
+ }
37
+ }
38
+
39
+ export function parentPathOf(path: string): string | undefined {
40
+ const index = path.lastIndexOf('.')
41
+ return index === -1 ? undefined : path.slice(0, index)
42
+ }
43
+
44
+ export function localIdOf(path: string): string {
45
+ return path.split('.').at(-1) ?? path
46
+ }
47
+
48
+ export function nextSystemOrder(model: OrganizationModel, parentPath?: string): number {
49
+ const siblings =
50
+ parentPath === undefined
51
+ ? listAllSystems(model).filter(({ path }) => !path.includes('.'))
52
+ : listAllSystems(model).filter(({ path }) => parentPathOf(path) === parentPath)
53
+ const maxOrder = siblings.reduce((max, { system }) => Math.max(max, system.order), 0)
54
+ return Math.ceil((maxOrder + 10) / 10) * 10
55
+ }
56
+
57
+ export function ontologyMapName(kind: OntologyKind): string {
58
+ const map: Record<OntologyKind, string> = {
59
+ object: 'objectTypes',
60
+ link: 'linkTypes',
61
+ action: 'actionTypes',
62
+ catalog: 'catalogTypes',
63
+ event: 'eventTypes',
64
+ interface: 'interfaceTypes',
65
+ 'value-type': 'valueTypes',
66
+ property: 'sharedProperties',
67
+ group: 'groups',
68
+ surface: 'surfaces'
69
+ }
70
+ return map[kind]
71
+ }
72
+
73
+ export function makeOntologyId(systemPath: string, kind: OntologyKind, localId: string): string {
74
+ return formatOntologyId({ scope: systemPath, kind, localId: slugify(localId) })
75
+ }
76
+
77
+ export function addProjectNextStep(plan: OmScaffoldPlan, enabled: boolean, command: string): OmScaffoldPlan {
78
+ if (!enabled) return plan
79
+ return {
80
+ ...plan,
81
+ projectCommand: command,
82
+ nextSteps: [...plan.nextSteps, `Run project handoff: ${command}`]
83
+ }
84
+ }
@@ -0,0 +1,19 @@
1
+ import type { OrganizationModel } from '..'
2
+ import { scaffoldKnowledgeNode } from './scaffoldKnowledgeNode'
3
+ import { scaffoldOntologyRecord } from './scaffoldOntologyRecord'
4
+ import { scaffoldResource } from './scaffoldResource'
5
+ import { scaffoldSystem } from './scaffoldSystem'
6
+ import type { OmScaffoldPlan, OmScaffoldSpec } from './types'
7
+
8
+ export function scaffoldOrganizationModel(model: OrganizationModel, spec: OmScaffoldSpec): OmScaffoldPlan {
9
+ if (spec.intent === 'system') return scaffoldSystem(model, spec)
10
+ if (spec.intent === 'ontology') return scaffoldOntologyRecord(model, spec)
11
+ if (spec.intent === 'resource') return scaffoldResource(model, spec)
12
+ return scaffoldKnowledgeNode(model, spec)
13
+ }
14
+
15
+ export * from './types'
16
+ export { scaffoldKnowledgeNode } from './scaffoldKnowledgeNode'
17
+ export { scaffoldOntologyRecord } from './scaffoldOntologyRecord'
18
+ export { scaffoldResource } from './scaffoldResource'
19
+ export { scaffoldSystem } from './scaffoldSystem'
@@ -0,0 +1,48 @@
1
+ import type { OrganizationModel } from '..'
2
+ import { assertSystemExists, slugify, titleize } from './helpers'
3
+ import type { KnowledgeNodeScaffoldSpec, OmScaffoldPlan } from './types'
4
+
5
+ export function scaffoldKnowledgeNode(model: OrganizationModel, spec: KnowledgeNodeScaffoldSpec): OmScaffoldPlan {
6
+ if (spec.systemPath !== undefined) assertSystemExists(model, spec.systemPath)
7
+ if (model.knowledge?.[spec.id] !== undefined) {
8
+ throw new Error(`knowledge node already exists: ${spec.id}`)
9
+ }
10
+
11
+ const title = spec.label ?? titleize(spec.id.replace(/^knowledge\./, ''))
12
+ const slug = slugify(spec.id.replace(/^knowledge\./, ''))
13
+ const kind = spec.kind ?? 'reference'
14
+ const links = spec.systemPath === undefined ? '' : `links:\n - system:${spec.systemPath}\n`
15
+ const ownerIds = spec.ownerRoleId === undefined ? '' : `ownerIds:\n - ${spec.ownerRoleId}\n`
16
+
17
+ return {
18
+ intent: 'knowledge',
19
+ id: spec.id,
20
+ summary: `Scaffold ${kind} knowledge node "${spec.id}".`,
21
+ writes: [
22
+ {
23
+ path: `packages/elevasis-core/src/knowledge/nodes/${slug}.mdx.stub`,
24
+ mode: 'create',
25
+ description: 'Knowledge node MDX skeleton.',
26
+ content: `---\nid: ${spec.id}\nkind: ${kind}\ntitle: ${JSON.stringify(title)}\nsummary: ${JSON.stringify(spec.description ?? `${title} knowledge node.`)}\n${links}${ownerIds}updatedAt: 2026-05-15\n---\n\n## Overview\n\nCapture the durable operating knowledge here.\n`
27
+ }
28
+ ],
29
+ edits: [
30
+ {
31
+ path: 'packages/elevasis-core/src/organization-model/knowledge.ts',
32
+ description: 'Register this generated node after replacing the .stub suffix.',
33
+ snippet: `${JSON.stringify(spec.id)}`
34
+ }
35
+ ],
36
+ warnings: [],
37
+ nextSteps: [
38
+ 'Replace the .stub suffix after the node is ready to become canonical.',
39
+ spec.systemPath === undefined
40
+ ? 'Add links to the OM nodes this knowledge governs.'
41
+ : `Run pnpm exec elevasis om:verify --scope ${spec.systemPath}.`
42
+ ],
43
+ projectCommand:
44
+ spec.withProject && spec.systemPath !== undefined
45
+ ? `pnpm exec elevasis project:create --link-om ${spec.systemPath} --title "Add ${title} knowledge" --kind om-change`
46
+ : undefined
47
+ }
48
+ }
@@ -0,0 +1,38 @@
1
+ import type { OrganizationModel } from '..'
2
+ import { assertSystemExists, makeOntologyId, ontologyMapName, titleize } from './helpers'
3
+ import type { OmScaffoldPlan, OntologyRecordScaffoldSpec } from './types'
4
+
5
+ export function scaffoldOntologyRecord(model: OrganizationModel, spec: OntologyRecordScaffoldSpec): OmScaffoldPlan {
6
+ assertSystemExists(model, spec.systemPath)
7
+ const localId = spec.localId ?? spec.id
8
+ const ontologyId = makeOntologyId(spec.systemPath, spec.kind, localId)
9
+ const label = spec.label ?? titleize(localId)
10
+ const mapName = ontologyMapName(spec.kind)
11
+
12
+ return {
13
+ intent: 'ontology',
14
+ id: ontologyId,
15
+ summary: `Scaffold ${spec.kind} ontology record "${ontologyId}".`,
16
+ writes: [],
17
+ edits: [
18
+ {
19
+ path: 'packages/elevasis-core/src/organization-model/systems.ts',
20
+ description: `Add this record under ${spec.systemPath}.ontology.${mapName}.`,
21
+ snippet: `${JSON.stringify(ontologyId)}: {
22
+ id: ${JSON.stringify(ontologyId)},
23
+ label: ${JSON.stringify(label)},
24
+ ownerSystemId: ${JSON.stringify(spec.systemPath)}${spec.description === undefined ? '' : `,
25
+ description: ${JSON.stringify(spec.description)}`}
26
+ }`
27
+ }
28
+ ],
29
+ warnings: [],
30
+ nextSteps: [
31
+ 'Wire any cross-references using canonical ontology IDs.',
32
+ `Run pnpm exec elevasis om:verify --scope ${spec.systemPath}.`
33
+ ],
34
+ projectCommand: spec.withProject
35
+ ? `pnpm exec elevasis project:create --link-om ${spec.systemPath} --title "Add ${label} ontology" --kind om-change`
36
+ : undefined
37
+ }
38
+ }
@@ -0,0 +1,59 @@
1
+ import type { OrganizationModel } from '..'
2
+ import { assertSystemExists, slugify, titleize } from './helpers'
3
+ import type { OmScaffoldPlan, ResourceScaffoldSpec } from './types'
4
+
5
+ export function scaffoldResource(model: OrganizationModel, spec: ResourceScaffoldSpec): OmScaffoldPlan {
6
+ assertSystemExists(model, spec.systemPath)
7
+ if (model.resources?.[spec.id] !== undefined) {
8
+ throw new Error(`resource already exists: ${spec.id}`)
9
+ }
10
+
11
+ const label = spec.label ?? titleize(spec.id)
12
+ const kind = spec.kind ?? 'workflow'
13
+ const slug = slugify(spec.id)
14
+ const writes = spec.withStubWorkflow
15
+ ? [
16
+ {
17
+ path: `packages/elevasis-core/src/workflows/${slug}.stub.ts`,
18
+ mode: 'create' as const,
19
+ description: 'Optional workflow implementation stub. Runtime wiring remains manual.',
20
+ content: `// Stub only. Replace with a real workflow implementation before registering the resource.\nexport const ${slug.replaceAll('-', '_')}Workflow = {\n id: ${JSON.stringify(spec.id)}\n}\n`
21
+ }
22
+ ]
23
+ : []
24
+
25
+ return {
26
+ intent: 'resource',
27
+ id: spec.id,
28
+ summary: `Scaffold ${kind} Resource "${spec.id}" for System "${spec.systemPath}".`,
29
+ writes,
30
+ edits: [
31
+ {
32
+ path: 'packages/elevasis-core/src/organization-model/resources.ts',
33
+ description: 'Add this descriptor to platformResources/platformResourceDescriptors.',
34
+ snippet: `${JSON.stringify(spec.id)}: {
35
+ id: ${JSON.stringify(spec.id)},
36
+ order: 0,
37
+ kind: ${JSON.stringify(kind)},
38
+ systemPath: ${JSON.stringify(spec.systemPath)},
39
+ title: ${JSON.stringify(label)},
40
+ ${spec.description === undefined ? '' : `description: ${JSON.stringify(spec.description)},\n `}${spec.ownerRoleId === undefined ? '' : `ownerRoleId: ${JSON.stringify(spec.ownerRoleId)},\n `}status: 'active',
41
+ codeRefs: []
42
+ }`
43
+ },
44
+ {
45
+ path: 'packages/elevasis-core/src/organization-model/topology.ts',
46
+ description: 'Add topology relationships only when this resource triggers, uses, or requires approval from another OM node.',
47
+ snippet: `// topologyRelationship({ from: topologyRef('resource', ${JSON.stringify(spec.id)}), kind: 'uses', to: ... })`
48
+ }
49
+ ],
50
+ warnings: ['Resource ontology bindings are intentionally omitted until action/read/write contracts are known.'],
51
+ nextSteps: [
52
+ 'Bind resource.ontology.actions/reads/writes after the ontology records exist.',
53
+ `Run pnpm exec elevasis om:verify --scope ${spec.systemPath}.`
54
+ ],
55
+ projectCommand: spec.withProject
56
+ ? `pnpm exec elevasis project:create --link-om ${spec.systemPath} --title "Add ${label} resource" --kind om-change`
57
+ : undefined
58
+ }
59
+ }
@@ -0,0 +1,110 @@
1
+ import type { OrganizationModel } from '..'
2
+ import {
3
+ addProjectNextStep,
4
+ assertSystemPathAvailable,
5
+ localIdOf,
6
+ nextSystemOrder,
7
+ parentPathOf,
8
+ slugify,
9
+ titleize
10
+ } from './helpers'
11
+ import type { OmScaffoldPlan, SystemScaffoldSpec } from './types'
12
+
13
+ export function scaffoldSystem(model: OrganizationModel, spec: SystemScaffoldSpec): OmScaffoldPlan {
14
+ const systemPath = spec.parent !== undefined && !spec.id.includes('.') ? `${spec.parent}.${spec.id}` : spec.id
15
+ assertSystemPathAvailable(model, systemPath)
16
+
17
+ const parentPath = parentPathOf(systemPath)
18
+ const localId = localIdOf(systemPath)
19
+ const label = spec.label ?? titleize(localId)
20
+ const roleId = spec.role ?? 'role.ops-lead'
21
+ const uiPath = spec.uiPath ?? `/${localId}`
22
+ const featureSlug = slugify(systemPath.replaceAll('.', '-'))
23
+ const knowledgeId = `knowledge.${featureSlug}-system-overview`
24
+ const order = nextSystemOrder(model, parentPath)
25
+ const withProject = spec.withProject ?? !spec.noProject
26
+
27
+ const systemEntry = ` ${JSON.stringify(localId)}: {
28
+ id: ${JSON.stringify(systemPath)},
29
+ order: ${order},
30
+ label: ${JSON.stringify(label)},
31
+ description: ${JSON.stringify(spec.description ?? `${label} bounded context.`)},
32
+ kind: ${JSON.stringify(spec.kind ?? 'operational')},
33
+ ${parentPath === undefined ? '' : `parentSystemId: ${JSON.stringify(parentPath)},\n `}responsibleRoleId: ${JSON.stringify(roleId)},
34
+ governedByKnowledge: [${JSON.stringify(knowledgeId)}],
35
+ drivesGoals: [],
36
+ lifecycle: 'draft',
37
+ ui: {
38
+ path: ${JSON.stringify(uiPath)},
39
+ surfaces: [],
40
+ ${spec.icon === undefined ? '' : `icon: ${JSON.stringify(spec.icon)},`}
41
+ }${spec.withOntology ? `,
42
+ ontology: {
43
+ objectTypes: {}
44
+ }` : ''}
45
+ }`
46
+
47
+ const plan: OmScaffoldPlan = {
48
+ intent: 'system',
49
+ id: systemPath,
50
+ summary: `Scaffold System "${systemPath}" with nav, role wiring, governing knowledge, and a UI manifest stub.`,
51
+ writes: [
52
+ {
53
+ path: `packages/ui/src/features/${featureSlug}/manifest.stub.ts`,
54
+ mode: 'create',
55
+ description: 'SystemModule manifest stub. Route files are intentionally not generated.',
56
+ content: `import type { SystemModule } from '@repo/ui'\n\nexport const ${featureSlug.replaceAll('-', '_')}Manifest: SystemModule = {\n systemId: ${JSON.stringify(systemPath)},\n label: ${JSON.stringify(label)},\n routes: []\n}\n`
57
+ },
58
+ {
59
+ path: `packages/elevasis-core/src/knowledge/nodes/${featureSlug}-system-overview.mdx.stub`,
60
+ mode: 'create',
61
+ description: 'Governing knowledge skeleton for the new System.',
62
+ content: `---\nid: ${knowledgeId}\nkind: reference\ntitle: ${JSON.stringify(`${label} System Overview`)}\nsummary: ${JSON.stringify(`Governing context for the ${label} System.`)}\nlinks:\n - system:${systemPath}\nownerIds:\n - ${roleId}\nupdatedAt: 2026-05-15\n---\n\n## Purpose\n\nDocument the operating boundaries, decisions, and ownership for ${label}.\n`
63
+ }
64
+ ],
65
+ edits: [
66
+ {
67
+ path: 'packages/elevasis-core/src/organization-model/systems.ts',
68
+ description:
69
+ parentPath === undefined
70
+ ? 'Add this entry to platformSystems.'
71
+ : `Add this entry under platformSystems ${parentPath}.systems.`,
72
+ snippet: systemEntry
73
+ },
74
+ {
75
+ path: 'packages/elevasis-core/src/organization-model/navigation.ts',
76
+ description: 'Confirm sidebar placement derives from ui.path or add explicit surface targeting if needed.',
77
+ snippet: `// System "${systemPath}" declares ui.path ${JSON.stringify(uiPath)}. Do not add route files in /om create.`
78
+ },
79
+ {
80
+ path: 'packages/elevasis-core/src/organization-model/roles.ts',
81
+ description: `Confirm ${roleId} exists or add the owning role before merging.`,
82
+ snippet: `// responsibleRoleId: ${JSON.stringify(roleId)}`
83
+ },
84
+ {
85
+ path: 'packages/elevasis-core/src/organization-model/assembly.ts',
86
+ description: 'Confirm roleFor()/owner routing covers the new System.',
87
+ snippet: `case ${JSON.stringify(systemPath)}:\n return ${JSON.stringify(roleId)}`
88
+ },
89
+ {
90
+ path: 'packages/elevasis-core/src/organization-model/knowledge.ts',
91
+ description: 'Register the generated governing knowledge node after replacing the .stub suffix.',
92
+ snippet: `${JSON.stringify(knowledgeId)}`
93
+ }
94
+ ],
95
+ warnings: spec.withOntology
96
+ ? ['Ontology was requested; the default objectTypes block is intentionally empty until the domain language is known.']
97
+ : ['Ontology is opt-in. Re-run with --with-ontology when the object/action/catalog language is known.'],
98
+ nextSteps: [
99
+ 'Review the planned OM edits and apply them in the listed source files.',
100
+ 'Replace .stub suffixes only after the System entry is merged.',
101
+ `Run pnpm exec elevasis om:verify --scope ${systemPath}.`
102
+ ]
103
+ }
104
+
105
+ return addProjectNextStep(
106
+ plan,
107
+ withProject,
108
+ `pnpm exec elevasis project:create --link-om ${systemPath} --title "Build ${label} System" --kind system-build`
109
+ )
110
+ }
@@ -0,0 +1,81 @@
1
+ import type {
2
+ OrganizationModelIconToken,
3
+ OrganizationModelResourceKind,
4
+ OrganizationModelSystemKind
5
+ } from '../types'
6
+ import type { OntologyKind } from '../ontology'
7
+
8
+ export type OmScaffoldIntent = 'system' | 'ontology' | 'resource' | 'knowledge'
9
+
10
+ export interface OmScaffoldWrite {
11
+ path: string
12
+ content: string
13
+ description: string
14
+ mode: 'create'
15
+ }
16
+
17
+ export interface OmScaffoldEdit {
18
+ path: string
19
+ description: string
20
+ snippet: string
21
+ }
22
+
23
+ export interface OmScaffoldPlan {
24
+ intent: OmScaffoldIntent
25
+ id: string
26
+ summary: string
27
+ writes: OmScaffoldWrite[]
28
+ edits: OmScaffoldEdit[]
29
+ warnings: string[]
30
+ nextSteps: string[]
31
+ projectCommand?: string
32
+ }
33
+
34
+ export interface BaseOmScaffoldSpec {
35
+ id: string
36
+ label?: string
37
+ description?: string
38
+ }
39
+
40
+ export interface SystemScaffoldSpec extends BaseOmScaffoldSpec {
41
+ intent: 'system'
42
+ parent?: string
43
+ kind?: OrganizationModelSystemKind
44
+ uiPath?: string
45
+ icon?: OrganizationModelIconToken
46
+ role?: string
47
+ withOntology?: boolean
48
+ noProject?: boolean
49
+ withProject?: boolean
50
+ }
51
+
52
+ export interface OntologyRecordScaffoldSpec extends BaseOmScaffoldSpec {
53
+ intent: 'ontology'
54
+ systemPath: string
55
+ kind: OntologyKind
56
+ localId?: string
57
+ withProject?: boolean
58
+ }
59
+
60
+ export interface ResourceScaffoldSpec extends BaseOmScaffoldSpec {
61
+ intent: 'resource'
62
+ systemPath: string
63
+ kind?: OrganizationModelResourceKind
64
+ ownerRoleId?: string
65
+ withStubWorkflow?: boolean
66
+ withProject?: boolean
67
+ }
68
+
69
+ export interface KnowledgeNodeScaffoldSpec extends BaseOmScaffoldSpec {
70
+ intent: 'knowledge'
71
+ systemPath?: string
72
+ kind?: 'playbook' | 'strategy' | 'reference'
73
+ ownerRoleId?: string
74
+ withProject?: boolean
75
+ }
76
+
77
+ export type OmScaffoldSpec =
78
+ | SystemScaffoldSpec
79
+ | OntologyRecordScaffoldSpec
80
+ | ResourceScaffoldSpec
81
+ | KnowledgeNodeScaffoldSpec