@elevasis/sdk 1.15.0 → 1.16.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.
- package/dist/cli.cjs +2325 -124
- package/dist/index.d.ts +882 -794
- package/dist/index.js +170 -46
- package/dist/node/index.d.ts +69 -0
- package/dist/node/index.js +273 -0
- package/dist/test-utils/index.d.ts +857 -711
- package/dist/test-utils/index.js +2 -0
- package/dist/types/worker/adapters/lead.d.ts +1 -1
- package/dist/types/worker/platform.d.ts +2 -9
- package/dist/worker/index.js +1 -0
- package/package.json +12 -3
- package/reference/_navigation.md +23 -1
- package/reference/_reference-manifest.json +98 -0
- package/reference/claude-config/rules/agent-start-here.md +13 -0
- package/reference/claude-config/rules/organization-model.md +40 -40
- package/reference/claude-config/rules/organization-os.md +16 -16
- package/reference/claude-config/rules/ui.md +2 -6
- package/reference/claude-config/rules/vibe.md +13 -13
- package/reference/claude-config/skills/knowledge/SKILL.md +253 -0
- package/reference/claude-config/skills/{configure → knowledge}/operations/codify-level-a.md +100 -100
- package/reference/claude-config/skills/{configure → knowledge}/operations/codify-level-b.md +158 -158
- package/reference/claude-config/skills/knowledge/operations/customers.md +109 -0
- package/reference/claude-config/skills/knowledge/operations/features.md +113 -0
- package/reference/claude-config/skills/knowledge/operations/goals.md +118 -0
- package/reference/claude-config/skills/knowledge/operations/identity.md +93 -0
- package/reference/claude-config/skills/knowledge/operations/labels.md +89 -0
- package/reference/claude-config/skills/knowledge/operations/offerings.md +109 -0
- package/reference/claude-config/skills/knowledge/operations/roles.md +99 -0
- package/reference/claude-config/skills/knowledge/operations/techStack.md +102 -0
- package/reference/claude-config/skills/run-ui/SKILL.md +73 -0
- package/reference/claude-config/skills/setup/SKILL.md +270 -270
- package/reference/claude-config/skills/tutorial/SKILL.md +249 -0
- package/reference/claude-config/skills/tutorial/progress-template.md +74 -0
- package/reference/claude-config/skills/tutorial/technical.md +1309 -0
- package/reference/claude-config/skills/tutorial/vibe-coder.md +890 -0
- package/reference/claude-config/sync-notes/2026-05-02-crm-ownership-next-action.md +58 -0
- package/reference/claude-config/sync-notes/2026-05-02-template-hardcode-workos-config.md +56 -0
- package/reference/claude-config/sync-notes/2026-05-04-elevasis-workspace.md +71 -0
- package/reference/claude-config/sync-notes/2026-05-04-template-skills-run-ui-and-tutorial.md +59 -0
- package/reference/deployment/index.mdx +5 -5
- package/reference/examples/organization-model.ts +40 -0
- package/reference/framework/index.mdx +1 -1
- package/reference/framework/tutorial-system.mdx +86 -173
- package/reference/packages/core/src/knowledge/README.md +32 -0
- package/reference/packages/ui/src/knowledge/README.md +31 -0
- package/reference/packages/ui/src/theme/presets/README.md +19 -0
- package/reference/scaffold/core/organization-model.mdx +1 -1
- package/reference/scaffold/recipes/add-a-feature.md +1 -1
- package/reference/scaffold/recipes/customize-crm-actions.md +3 -3
- package/reference/scaffold/recipes/customize-organization-model.md +3 -3
- package/reference/scaffold/recipes/extend-crm.md +12 -8
- package/reference/scaffold/recipes/extend-lead-gen.md +129 -20
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +1 -1
- package/reference/scaffold/recipes/index.md +6 -0
- package/reference/scaffold/reference/contracts.md +829 -595
- package/reference/scaffold/reference/feature-registry.md +2 -1
- package/reference/scaffold/ui/composition-extensibility.mdx +17 -0
- package/reference/claude-config/skills/configure/SKILL.md +0 -98
- package/reference/claude-config/skills/configure/operations/customers.md +0 -150
- package/reference/claude-config/skills/configure/operations/features.md +0 -162
- package/reference/claude-config/skills/configure/operations/goals.md +0 -147
- package/reference/claude-config/skills/configure/operations/identity.md +0 -133
- package/reference/claude-config/skills/configure/operations/labels.md +0 -128
- package/reference/claude-config/skills/configure/operations/offerings.md +0 -159
- package/reference/claude-config/skills/configure/operations/roles.md +0 -153
- package/reference/claude-config/skills/configure/operations/techStack.md +0 -139
|
@@ -1,158 +1,158 @@
|
|
|
1
|
-
# Codify Pipeline: Level B (New Extension TypeScript Files)
|
|
2
|
-
|
|
3
|
-
Level B is the codify pipeline for changes that require creating a new TypeScript file under
|
|
4
|
-
`foundations/config/extensions/`. This pipeline is used when the user wants to add a custom
|
|
5
|
-
feature, a custom entity type, or any structural addition that cannot be expressed as a simple
|
|
6
|
-
field override in `foundations/config/organization-model.ts`.
|
|
7
|
-
|
|
8
|
-
Level B is **only offered when the user explicitly asks** for something that requires a new file.
|
|
9
|
-
Never silently escalate from Level A to Level B. If Level A is sufficient, use it.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## When Level B applies
|
|
14
|
-
|
|
15
|
-
- Adding a custom feature that does not exist in the platform defaults (new `FeatureSchema` entry
|
|
16
|
-
with a custom ID, manifest wiring, and route references)
|
|
17
|
-
- Adding a custom entity extension (new Zod schema extending a base entity type)
|
|
18
|
-
- Any structural addition the caller's domain operation has determined cannot be expressed as a
|
|
19
|
-
field value in the existing adapter
|
|
20
|
-
|
|
21
|
-
The calling operation (e.g. `features.md`) is responsible for deciding when Level B is needed
|
|
22
|
-
and for confirming the intent with the user before invoking this pipeline.
|
|
23
|
-
|
|
24
|
-
---
|
|
25
|
-
|
|
26
|
-
## Pipeline
|
|
27
|
-
|
|
28
|
-
### Step 1: Snapshot all files that will be touched
|
|
29
|
-
|
|
30
|
-
Before any write, read and snapshot:
|
|
31
|
-
|
|
32
|
-
1. `foundations/config/organization-model.ts` (always touched for wiring)
|
|
33
|
-
2. The target extension file path (if it already exists -- confirm overwrite with user)
|
|
34
|
-
|
|
35
|
-
```
|
|
36
|
-
Read("foundations/config/organization-model.ts") -- store as ROLLBACK_ADAPTER
|
|
37
|
-
Read("foundations/config/extensions/{target}.ts") -- store as ROLLBACK_EXTENSION (if exists)
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
The target extension file path follows the naming convention:
|
|
41
|
-
`foundations/config/extensions/{kebab-case-feature-id}.ts`
|
|
42
|
-
|
|
43
|
-
### Step 2: Scaffold the extension file
|
|
44
|
-
|
|
45
|
-
Create `foundations/config/extensions/{id}.ts` using the Write tool.
|
|
46
|
-
|
|
47
|
-
The file shape depends on the extension type:
|
|
48
|
-
|
|
49
|
-
**Custom feature (most common Level B case):**
|
|
50
|
-
|
|
51
|
-
```typescript
|
|
52
|
-
/**
|
|
53
|
-
* {Feature label} feature extension.
|
|
54
|
-
* Registered in foundations/config/organization-model.ts.
|
|
55
|
-
*/
|
|
56
|
-
import type { OrganizationModelFeature } from '@elevasis/core/organization-model'
|
|
57
|
-
|
|
58
|
-
export const {FEATURE_CONST}: OrganizationModelFeature = {
|
|
59
|
-
id: '{feature-id}',
|
|
60
|
-
label: '{Feature Label}',
|
|
61
|
-
description: '{optional description}',
|
|
62
|
-
enabled: true,
|
|
63
|
-
entityIds: [],
|
|
64
|
-
surfaceIds: [],
|
|
65
|
-
resourceIds: [],
|
|
66
|
-
capabilityIds: [],
|
|
67
|
-
}
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
Replace `{FEATURE_CONST}` with the SCREAMING_SNAKE_CASE version of the feature ID
|
|
71
|
-
(e.g. `CLIENT_PORTAL_FEATURE`).
|
|
72
|
-
|
|
73
|
-
The caller provides the exact field values based on what the user confirmed.
|
|
74
|
-
|
|
75
|
-
### Step 3: Wire the extension into the adapter
|
|
76
|
-
|
|
77
|
-
Edit `foundations/config/organization-model.ts` to:
|
|
78
|
-
|
|
79
|
-
1. Import the new constant from the extension file.
|
|
80
|
-
2. Add it to the `features` array in the `defineOrganizationModel({...})` call.
|
|
81
|
-
|
|
82
|
-
Example import addition:
|
|
83
|
-
|
|
84
|
-
```typescript
|
|
85
|
-
import { CLIENT_PORTAL_FEATURE } from './extensions/client-portal'
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Example features array addition:
|
|
89
|
-
|
|
90
|
-
```typescript
|
|
91
|
-
features: [
|
|
92
|
-
...existingFeatures,
|
|
93
|
-
CLIENT_PORTAL_FEATURE,
|
|
94
|
-
],
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
### Step 4: TypeScript type-check
|
|
98
|
-
|
|
99
|
-
```bash
|
|
100
|
-
pnpm -C operations check-types
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Capture stdout and stderr. If the command exits non-zero, proceed to Step 6 (rollback).
|
|
104
|
-
|
|
105
|
-
### Step 5: Runtime schema validation
|
|
106
|
-
|
|
107
|
-
```bash
|
|
108
|
-
pnpm -C operations check
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
If either check fails, proceed to Step 6 (rollback).
|
|
112
|
-
|
|
113
|
-
### Step 6: Rollback (on failure only)
|
|
114
|
-
|
|
115
|
-
If Step 4 or Step 5 failed:
|
|
116
|
-
|
|
117
|
-
1. Restore `foundations/config/organization-model.ts` from ROLLBACK_ADAPTER.
|
|
118
|
-
2. If the extension file did not previously exist, delete it. If it previously existed, restore
|
|
119
|
-
from ROLLBACK_EXTENSION.
|
|
120
|
-
3. Re-run `pnpm -C operations check-types` to confirm the restore is clean. If the restore
|
|
121
|
-
itself fails type-check, report both the original error and the restore state to the user --
|
|
122
|
-
do not silently leave the project in a broken state.
|
|
123
|
-
4. Return the error message to the caller.
|
|
124
|
-
|
|
125
|
-
### Step 7: Success signal
|
|
126
|
-
|
|
127
|
-
If Steps 4 and 5 both passed, return a success signal to the caller with:
|
|
128
|
-
|
|
129
|
-
- Extension file path created
|
|
130
|
-
- Adapter wiring changes (import + features array entry)
|
|
131
|
-
- `Type-check: PASS`
|
|
132
|
-
- `Schema validation: PASS`
|
|
133
|
-
|
|
134
|
-
The caller formats and presents the final report to the user.
|
|
135
|
-
|
|
136
|
-
---
|
|
137
|
-
|
|
138
|
-
## Caller Contract
|
|
139
|
-
|
|
140
|
-
Callers must provide before invoking this pipeline:
|
|
141
|
-
|
|
142
|
-
- **Extension file path:** `foundations/config/extensions/{id}.ts`
|
|
143
|
-
- **Extension file content:** the full TypeScript content for the new file
|
|
144
|
-
- **Adapter changes:** the exact import line and features-array addition to write into the adapter
|
|
145
|
-
- **Confirmed:** the user has already said yes to the proposed change and explicitly requested
|
|
146
|
-
a new extension file
|
|
147
|
-
|
|
148
|
-
This pipeline does not ask the user any questions. All confirmation and escalation decisions
|
|
149
|
-
happen in the domain operation before this pipeline is invoked.
|
|
150
|
-
|
|
151
|
-
---
|
|
152
|
-
|
|
153
|
-
## Constraint: Extension files are Tier 3 (never synced)
|
|
154
|
-
|
|
155
|
-
Files under `foundations/config/extensions/` are Tier 3 -- project-specific, never overwritten
|
|
156
|
-
by `/external sync`. This means custom features and entity extensions survive template upgrades
|
|
157
|
-
automatically. Do not put platform-default overrides in extension files; those belong directly in
|
|
158
|
-
`foundations/config/organization-model.ts` (Tier 2, merge-aware).
|
|
1
|
+
# Codify Pipeline: Level B (New Extension TypeScript Files)
|
|
2
|
+
|
|
3
|
+
Level B is the codify pipeline for changes that require creating a new TypeScript file under
|
|
4
|
+
`foundations/config/extensions/`. This pipeline is used when the user wants to add a custom
|
|
5
|
+
feature, a custom entity type, or any structural addition that cannot be expressed as a simple
|
|
6
|
+
field override in `foundations/config/organization-model.ts`.
|
|
7
|
+
|
|
8
|
+
Level B is **only offered when the user explicitly asks** for something that requires a new file.
|
|
9
|
+
Never silently escalate from Level A to Level B. If Level A is sufficient, use it.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## When Level B applies
|
|
14
|
+
|
|
15
|
+
- Adding a custom feature that does not exist in the platform defaults (new `FeatureSchema` entry
|
|
16
|
+
with a custom ID, manifest wiring, and route references)
|
|
17
|
+
- Adding a custom entity extension (new Zod schema extending a base entity type)
|
|
18
|
+
- Any structural addition the caller's domain operation has determined cannot be expressed as a
|
|
19
|
+
field value in the existing adapter
|
|
20
|
+
|
|
21
|
+
The calling operation (e.g. `features.md`) is responsible for deciding when Level B is needed
|
|
22
|
+
and for confirming the intent with the user before invoking this pipeline.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Pipeline
|
|
27
|
+
|
|
28
|
+
### Step 1: Snapshot all files that will be touched
|
|
29
|
+
|
|
30
|
+
Before any write, read and snapshot:
|
|
31
|
+
|
|
32
|
+
1. `foundations/config/organization-model.ts` (always touched for wiring)
|
|
33
|
+
2. The target extension file path (if it already exists -- confirm overwrite with user)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
Read("foundations/config/organization-model.ts") -- store as ROLLBACK_ADAPTER
|
|
37
|
+
Read("foundations/config/extensions/{target}.ts") -- store as ROLLBACK_EXTENSION (if exists)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
The target extension file path follows the naming convention:
|
|
41
|
+
`foundations/config/extensions/{kebab-case-feature-id}.ts`
|
|
42
|
+
|
|
43
|
+
### Step 2: Scaffold the extension file
|
|
44
|
+
|
|
45
|
+
Create `foundations/config/extensions/{id}.ts` using the Write tool.
|
|
46
|
+
|
|
47
|
+
The file shape depends on the extension type:
|
|
48
|
+
|
|
49
|
+
**Custom feature (most common Level B case):**
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
/**
|
|
53
|
+
* {Feature label} feature extension.
|
|
54
|
+
* Registered in foundations/config/organization-model.ts.
|
|
55
|
+
*/
|
|
56
|
+
import type { OrganizationModelFeature } from '@elevasis/core/organization-model'
|
|
57
|
+
|
|
58
|
+
export const {FEATURE_CONST}: OrganizationModelFeature = {
|
|
59
|
+
id: '{feature-id}',
|
|
60
|
+
label: '{Feature Label}',
|
|
61
|
+
description: '{optional description}',
|
|
62
|
+
enabled: true,
|
|
63
|
+
entityIds: [],
|
|
64
|
+
surfaceIds: [],
|
|
65
|
+
resourceIds: [],
|
|
66
|
+
capabilityIds: [],
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Replace `{FEATURE_CONST}` with the SCREAMING_SNAKE_CASE version of the feature ID
|
|
71
|
+
(e.g. `CLIENT_PORTAL_FEATURE`).
|
|
72
|
+
|
|
73
|
+
The caller provides the exact field values based on what the user confirmed.
|
|
74
|
+
|
|
75
|
+
### Step 3: Wire the extension into the adapter
|
|
76
|
+
|
|
77
|
+
Edit `foundations/config/organization-model.ts` to:
|
|
78
|
+
|
|
79
|
+
1. Import the new constant from the extension file.
|
|
80
|
+
2. Add it to the `features` array in the `defineOrganizationModel({...})` call.
|
|
81
|
+
|
|
82
|
+
Example import addition:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { CLIENT_PORTAL_FEATURE } from './extensions/client-portal'
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
Example features array addition:
|
|
89
|
+
|
|
90
|
+
```typescript
|
|
91
|
+
features: [
|
|
92
|
+
...existingFeatures,
|
|
93
|
+
CLIENT_PORTAL_FEATURE,
|
|
94
|
+
],
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Step 4: TypeScript type-check
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
pnpm -C operations check-types
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Capture stdout and stderr. If the command exits non-zero, proceed to Step 6 (rollback).
|
|
104
|
+
|
|
105
|
+
### Step 5: Runtime schema validation
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
pnpm -C operations check
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
If either check fails, proceed to Step 6 (rollback).
|
|
112
|
+
|
|
113
|
+
### Step 6: Rollback (on failure only)
|
|
114
|
+
|
|
115
|
+
If Step 4 or Step 5 failed:
|
|
116
|
+
|
|
117
|
+
1. Restore `foundations/config/organization-model.ts` from ROLLBACK_ADAPTER.
|
|
118
|
+
2. If the extension file did not previously exist, delete it. If it previously existed, restore
|
|
119
|
+
from ROLLBACK_EXTENSION.
|
|
120
|
+
3. Re-run `pnpm -C operations check-types` to confirm the restore is clean. If the restore
|
|
121
|
+
itself fails type-check, report both the original error and the restore state to the user --
|
|
122
|
+
do not silently leave the project in a broken state.
|
|
123
|
+
4. Return the error message to the caller.
|
|
124
|
+
|
|
125
|
+
### Step 7: Success signal
|
|
126
|
+
|
|
127
|
+
If Steps 4 and 5 both passed, return a success signal to the caller with:
|
|
128
|
+
|
|
129
|
+
- Extension file path created
|
|
130
|
+
- Adapter wiring changes (import + features array entry)
|
|
131
|
+
- `Type-check: PASS`
|
|
132
|
+
- `Schema validation: PASS`
|
|
133
|
+
|
|
134
|
+
The caller formats and presents the final report to the user.
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## Caller Contract
|
|
139
|
+
|
|
140
|
+
Callers must provide before invoking this pipeline:
|
|
141
|
+
|
|
142
|
+
- **Extension file path:** `foundations/config/extensions/{id}.ts`
|
|
143
|
+
- **Extension file content:** the full TypeScript content for the new file
|
|
144
|
+
- **Adapter changes:** the exact import line and features-array addition to write into the adapter
|
|
145
|
+
- **Confirmed:** the user has already said yes to the proposed change and explicitly requested
|
|
146
|
+
a new extension file
|
|
147
|
+
|
|
148
|
+
This pipeline does not ask the user any questions. All confirmation and escalation decisions
|
|
149
|
+
happen in the domain operation before this pipeline is invoked.
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## Constraint: Extension files are Tier 3 (never synced)
|
|
154
|
+
|
|
155
|
+
Files under `foundations/config/extensions/` are Tier 3 -- project-specific, never overwritten
|
|
156
|
+
by `/external sync`. This means custom features and entity extensions survive template upgrades
|
|
157
|
+
automatically. Do not put platform-default overrides in extension files; those belong directly in
|
|
158
|
+
`foundations/config/organization-model.ts` (Tier 2, merge-aware).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Customers domain
|
|
2
|
+
|
|
3
|
+
The `customers` domain describes who the organization serves — distinct buyer archetypes modeled
|
|
4
|
+
after the Value Proposition Canvas (BMC / VPC). Each segment captures jobs-to-be-done, pains,
|
|
5
|
+
gains, firmographics, and a value proposition. Agents use these segments for targeting, outreach
|
|
6
|
+
context, and personalization.
|
|
7
|
+
|
|
8
|
+
## Schema
|
|
9
|
+
|
|
10
|
+
Source: `packages/core/src/organization-model/domains/customers.ts`
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
CustomersDomainSchema = z.object({
|
|
14
|
+
segments: z.array(CustomerSegmentSchema).default([])
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
CustomerSegmentSchema = z.object({
|
|
18
|
+
id: z.string().trim().min(1).max(100), // stable ID, e.g. "segment-smb-agencies"
|
|
19
|
+
name: z.string().trim().max(200).default(''), // display name
|
|
20
|
+
description: z.string().trim().max(2000).default(''), // who this segment is
|
|
21
|
+
jobsToBeDone: z.string().trim().max(2000).default(''), // the goal they hire you to accomplish
|
|
22
|
+
pains: z.array(z.string().trim().max(500)).default([]),
|
|
23
|
+
gains: z.array(z.string().trim().max(500)).default([]),
|
|
24
|
+
firmographics: FirmographicsSchema.default({}), // industry, companySize, region
|
|
25
|
+
valueProp: z.string().trim().max(2000).default('') // why your offering fits this segment
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
FirmographicsSchema = z.object({
|
|
29
|
+
industry: z.string().trim().max(200).optional(), // e.g. "Marketing Agency"
|
|
30
|
+
companySize: z.string().trim().max(100).optional(), // e.g. "11–50"
|
|
31
|
+
region: z.string().trim().max(200).optional() // e.g. "North America"
|
|
32
|
+
})
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Field reference
|
|
36
|
+
|
|
37
|
+
| Field | Type | Max | Notes |
|
|
38
|
+
| --------------- | -------- | ---- | ------------------------------------------------------------ |
|
|
39
|
+
| `id` | string | 100 | Stable key, min 1 char; e.g. `"segment-smb-agencies"` |
|
|
40
|
+
| `name` | string | 200 | Display name |
|
|
41
|
+
| `description` | string | 2000 | Who this segment is in one or two sentences |
|
|
42
|
+
| `jobsToBeDone` | string | 2000 | The goal they hire you to accomplish, in their terms |
|
|
43
|
+
| `pains` | string[] | 500 | Each item: a frustration or obstacle |
|
|
44
|
+
| `gains` | string[] | 500 | Each item: an outcome or benefit they hope for |
|
|
45
|
+
| `firmographics` | object | -- | Optional industry, companySize, region filters for targeting |
|
|
46
|
+
| `valueProp` | string | 2000 | Why your offering uniquely addresses this segment's needs |
|
|
47
|
+
|
|
48
|
+
## Validation rules
|
|
49
|
+
|
|
50
|
+
- `id` is the stable key used by `offerings.products[].targetSegmentIds` references; once set,
|
|
51
|
+
changing the `id` of a segment breaks any offering that references it
|
|
52
|
+
- `firmographics` is optional; all three sub-fields (`industry`, `companySize`, `region`) are
|
|
53
|
+
individually optional
|
|
54
|
+
- `pains` and `gains` default to empty arrays; agents should treat an empty array as unconfigured
|
|
55
|
+
- There is no uniqueness constraint enforced by the schema on `id`, but agents must treat it as
|
|
56
|
+
unique and surface duplicates if found
|
|
57
|
+
- Cross-reference: if a segment is removed, any `offerings.products[].targetSegmentIds` that
|
|
58
|
+
reference its `id` become dangling references; surface a warning before removing
|
|
59
|
+
|
|
60
|
+
## Examples
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
customers: {
|
|
64
|
+
segments: [
|
|
65
|
+
{
|
|
66
|
+
id: "segment-smb-agencies",
|
|
67
|
+
name: "SMB Marketing Agencies",
|
|
68
|
+
description: "Owner-operated agencies with 1–15 employees running campaign delivery for SMB clients.",
|
|
69
|
+
jobsToBeDone: "Deliver consistent client results without adding headcount.",
|
|
70
|
+
pains: [
|
|
71
|
+
"Manual campaign QA eats time",
|
|
72
|
+
"Client reporting takes hours each week",
|
|
73
|
+
"Hard to scale without hiring"
|
|
74
|
+
],
|
|
75
|
+
gains: [
|
|
76
|
+
"More client capacity without more staff",
|
|
77
|
+
"Predictable delivery timelines"
|
|
78
|
+
],
|
|
79
|
+
firmographics: {
|
|
80
|
+
industry: "Marketing Agency",
|
|
81
|
+
companySize: "1–15",
|
|
82
|
+
region: "North America"
|
|
83
|
+
},
|
|
84
|
+
valueProp: "Automates the repetitive delivery and reporting work so agencies can take on more clients."
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## Where it lives in the adapter
|
|
91
|
+
|
|
92
|
+
`foundations/config/organization-model.ts` under the `customers` key of
|
|
93
|
+
`defineOrganizationModel({...})`.
|
|
94
|
+
|
|
95
|
+
To read current segments: open the adapter file and inspect the `customers.segments` array, or
|
|
96
|
+
use `pnpm exec elevasis-sdk knowledge:cat customers` (external project).
|
|
97
|
+
|
|
98
|
+
## Write path
|
|
99
|
+
|
|
100
|
+
To add, edit, or remove a segment, the `/knowledge` skill runs the codify ceremony
|
|
101
|
+
(`operations/codify-level-a.md`): snapshot → propose → confirm → write → typecheck → Zod parse →
|
|
102
|
+
rollback on failure. Only the `segments` array is written; no other keys in the adapter are
|
|
103
|
+
touched. When adding, append to the array. When editing, replace the matching entry by `id`.
|
|
104
|
+
When removing, filter it out — and surface any dangling `targetSegmentIds` references first.
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
**Read via `/knowledge`** — natural-language queries like "who are our customer segments?" or
|
|
109
|
+
"what pains does the agency segment have?" route to this domain via the skill's intent classifier.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Features domain
|
|
2
|
+
|
|
3
|
+
The `features` domain controls top-level capability switches in the platform. Each entry in the
|
|
4
|
+
`features` array of the OrganizationModel governs whether a feature's nav items, routes, and
|
|
5
|
+
surfaces render. Disabling a feature hides it without removing it from the model; enabling makes
|
|
6
|
+
it visible. Custom features extend the platform's defaults via a TypeScript extension file.
|
|
7
|
+
|
|
8
|
+
## Schema
|
|
9
|
+
|
|
10
|
+
Source: `@elevasis/core/organization-model` (published types) or
|
|
11
|
+
`node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md` (generated shapes).
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
FeatureSchema = z.object({
|
|
15
|
+
id: ModelIdSchema, // lowercase, e.g. "crm", "lead-gen", "seo"
|
|
16
|
+
label: LabelSchema, // display label
|
|
17
|
+
description: DescriptionSchema.optional(),
|
|
18
|
+
enabled: z.boolean().default(true),
|
|
19
|
+
color: ColorTokenSchema.optional(),
|
|
20
|
+
icon: IconNameSchema.optional(),
|
|
21
|
+
entityIds: ReferenceIdsSchema,
|
|
22
|
+
surfaceIds: ReferenceIdsSchema,
|
|
23
|
+
resourceIds: ReferenceIdsSchema,
|
|
24
|
+
capabilityIds: ReferenceIdsSchema,
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Lives at: `core/config/organization-model.ts` under the `features` array of
|
|
29
|
+
`defineOrganizationModel({...})`. The `features` array replaces entirely (no per-element merge), so
|
|
30
|
+
the adapter must redeclare every feature it wants to override.
|
|
31
|
+
|
|
32
|
+
## Platform default feature IDs
|
|
33
|
+
|
|
34
|
+
`crm`, `lead-gen`, `projects`, `operations`, `monitoring`, `settings`, `seo`
|
|
35
|
+
|
|
36
|
+
Source of truth: `node_modules/@elevasis/sdk/reference/scaffold/reference/contracts.md`. Use the
|
|
37
|
+
typed feature constants from `@elevasis/core/organization-model` (`CRM_FEATURE_ID`,
|
|
38
|
+
`LEAD_GEN_FEATURE_ID`, etc.) instead of magic strings when overriding.
|
|
39
|
+
|
|
40
|
+
## Levels
|
|
41
|
+
|
|
42
|
+
Two levels of feature change, both gated by the codify ceremony:
|
|
43
|
+
|
|
44
|
+
- **Level A (config-only edit)** -- toggle `enabled`, adjust label/color/icon, or override
|
|
45
|
+
metadata on a feature that already exists in the platform defaults. No new TypeScript files. See
|
|
46
|
+
`operations/codify-level-a.md`.
|
|
47
|
+
|
|
48
|
+
- **Level B (new extension file)** -- introduce a custom feature ID that does not exist in the
|
|
49
|
+
platform defaults. Requires a new file under `core/config/extensions/` plus wiring it into the
|
|
50
|
+
adapter. Level B is reserved for explicit user requests. See `operations/codify-level-b.md`.
|
|
51
|
+
|
|
52
|
+
## Validation rules
|
|
53
|
+
|
|
54
|
+
- `id` is lowercase, hyphens only (e.g. `client-portal`); enforces `ModelIdSchema`.
|
|
55
|
+
- `label` is non-empty, max 120 characters.
|
|
56
|
+
- The `features` array replaces entirely on override -- entries omitted from the adapter are
|
|
57
|
+
dropped, even if they appear in the platform defaults.
|
|
58
|
+
- A new custom feature ID must not collide with any platform default ID.
|
|
59
|
+
|
|
60
|
+
## Realistic examples
|
|
61
|
+
|
|
62
|
+
Toggle a default feature off:
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
defineOrganizationModel({
|
|
66
|
+
features: [
|
|
67
|
+
// ... redeclare every default feature you want to keep ...
|
|
68
|
+
{ id: SEO_FEATURE_ID, label: 'SEO', enabled: false, /* ... */ },
|
|
69
|
+
],
|
|
70
|
+
})
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Add a custom feature (Level B):
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// core/config/extensions/client-portal.ts
|
|
77
|
+
export const clientPortalFeature = {
|
|
78
|
+
id: 'client-portal',
|
|
79
|
+
label: 'Client Portal',
|
|
80
|
+
description: 'Self-serve project status for clients',
|
|
81
|
+
enabled: true,
|
|
82
|
+
entityIds: ['project', 'deliverable'],
|
|
83
|
+
surfaceIds: ['client-portal-dashboard'],
|
|
84
|
+
resourceIds: [],
|
|
85
|
+
capabilityIds: [],
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// core/config/organization-model.ts
|
|
89
|
+
import { clientPortalFeature } from './extensions/client-portal'
|
|
90
|
+
defineOrganizationModel({
|
|
91
|
+
features: [
|
|
92
|
+
/* ... defaults you want to keep ... */
|
|
93
|
+
clientPortalFeature,
|
|
94
|
+
],
|
|
95
|
+
})
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Validation gate
|
|
99
|
+
|
|
100
|
+
Every change must pass before codify completes:
|
|
101
|
+
|
|
102
|
+
1. `pnpm -C operations check-types` -- TypeScript compilation succeeds.
|
|
103
|
+
2. `resolveOrganizationModel()` and `OrganizationModelSchema.parse()` succeed on the merged result.
|
|
104
|
+
|
|
105
|
+
On failure, the codify ceremony rolls back. See `operations/codify-level-a.md` and
|
|
106
|
+
`operations/codify-level-b.md` for the rollback procedure.
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
> **Read via `/knowledge`** -- natural-language queries like "what features are enabled?" or
|
|
111
|
+
> "is the SEO feature on?" route to this domain via the skill's intent classifier. To enable,
|
|
112
|
+
> disable, or add a custom feature, the `/knowledge` skill triggers the codify ceremony when
|
|
113
|
+
> intent classifies as Toggle or Codify.
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# Goals domain
|
|
2
|
+
|
|
3
|
+
The `goals` domain captures what the organization is working toward — time-bounded goals with
|
|
4
|
+
measurable outcomes. The schema shape is OKR-inspired (objectives + key results) but all
|
|
5
|
+
user-facing language must say "goals" and "measurable outcomes". Never say "OKR", "objective",
|
|
6
|
+
or "key result" to the user.
|
|
7
|
+
|
|
8
|
+
Agents use this domain for quarterly planning, priority routing, and understanding which outcomes
|
|
9
|
+
matter most right now.
|
|
10
|
+
|
|
11
|
+
## Schema
|
|
12
|
+
|
|
13
|
+
Source: `packages/core/src/organization-model/domains/goals.ts`
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
GoalsDomainSchema = z.object({
|
|
17
|
+
objectives: z.array(ObjectiveSchema).default([])
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
ObjectiveSchema = z.object({
|
|
21
|
+
id: z.string().trim().min(1).max(100), // stable ID, e.g. "goal-grow-arr-q1-2026"
|
|
22
|
+
description: z.string().trim().min(1).max(1000), // plain-language goal statement
|
|
23
|
+
periodStart: z.string().regex(ISO_DATE), // YYYY-MM-DD — must be before periodEnd
|
|
24
|
+
periodEnd: z.string().regex(ISO_DATE), // YYYY-MM-DD — enforced in superRefine
|
|
25
|
+
keyResults: z.array(KeyResultSchema).default([]) // measurable outcomes under this goal
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
KeyResultSchema = z.object({
|
|
29
|
+
id: z.string().trim().min(1).max(100), // e.g. "kr-revenue-q1"
|
|
30
|
+
description: z.string().trim().min(1).max(500), // e.g. "Increase trial-to-paid conversion"
|
|
31
|
+
targetMetric: z.string().trim().min(1).max(200), // what is being measured, e.g. "monthly revenue"
|
|
32
|
+
currentValue: z.number().default(0), // current tracked value
|
|
33
|
+
targetValue: z.number().optional() // target to hit (omit if directional)
|
|
34
|
+
})
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Field reference
|
|
38
|
+
|
|
39
|
+
| Field | Type | Notes |
|
|
40
|
+
| ------------- | ------------- | ---------------------------------------------------------- |
|
|
41
|
+
| `id` | string (100) | Stable key; e.g. `"goal-grow-arr-q1-2026"` |
|
|
42
|
+
| `description` | string (1000) | Plain-language goal statement; min 1 char required |
|
|
43
|
+
| `periodStart` | string | ISO date `YYYY-MM-DD`; must be strictly before `periodEnd` |
|
|
44
|
+
| `periodEnd` | string | ISO date `YYYY-MM-DD`; enforced by `superRefine` |
|
|
45
|
+
| `keyResults` | array | Measurable outcomes under this goal; defaults to `[]` |
|
|
46
|
+
|
|
47
|
+
Key result fields:
|
|
48
|
+
|
|
49
|
+
| Field | Type | Notes |
|
|
50
|
+
| -------------- | ------------ | --------------------------------------------------- |
|
|
51
|
+
| `id` | string (100) | Stable key; e.g. `"kr-revenue-q1"` |
|
|
52
|
+
| `description` | string (500) | What is being tracked; min 1 char required |
|
|
53
|
+
| `targetMetric` | string (200) | The metric name; e.g. `"monthly recurring revenue"` |
|
|
54
|
+
| `currentValue` | number | Current value; defaults to `0` |
|
|
55
|
+
| `targetValue` | number | Optional target; omit if the outcome is directional |
|
|
56
|
+
|
|
57
|
+
## Validation rules
|
|
58
|
+
|
|
59
|
+
- `periodEnd` must be strictly after `periodStart`; enforced at parse time by
|
|
60
|
+
`OrganizationModelSchema.superRefine()`; setting equal dates is also invalid
|
|
61
|
+
- Both `periodStart` and `periodEnd` must match `YYYY-MM-DD` ISO date format exactly
|
|
62
|
+
- The internal field name for the goals array is `objectives` (not `goals`) — this is a
|
|
63
|
+
schema-level name, not user-facing vocabulary; always say "goals" to users
|
|
64
|
+
- The internal field name for measurable outcomes is `keyResults` (not `outcomes`) — same
|
|
65
|
+
convention applies; say "measurable outcomes" to users
|
|
66
|
+
- `targetValue` is optional for directional goals where there is no specific number target
|
|
67
|
+
|
|
68
|
+
## Examples
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
goals: {
|
|
72
|
+
objectives: [
|
|
73
|
+
{
|
|
74
|
+
id: "goal-arr-q1-2026",
|
|
75
|
+
description: "Reach $50K MRR by end of Q1 2026",
|
|
76
|
+
periodStart: "2026-01-01",
|
|
77
|
+
periodEnd: "2026-03-31",
|
|
78
|
+
keyResults: [
|
|
79
|
+
{
|
|
80
|
+
id: "kr-mrr-q1",
|
|
81
|
+
description: "Grow monthly recurring revenue",
|
|
82
|
+
targetMetric: "monthly recurring revenue (MRR)",
|
|
83
|
+
currentValue: 32000,
|
|
84
|
+
targetValue: 50000
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "kr-churn-q1",
|
|
88
|
+
description: "Reduce monthly churn rate",
|
|
89
|
+
targetMetric: "monthly churn rate (%)",
|
|
90
|
+
currentValue: 4.2,
|
|
91
|
+
targetValue: 2.5
|
|
92
|
+
}
|
|
93
|
+
]
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Where it lives in the adapter
|
|
100
|
+
|
|
101
|
+
`foundations/config/organization-model.ts` under the `goals` key of
|
|
102
|
+
`defineOrganizationModel({...})`.
|
|
103
|
+
|
|
104
|
+
To read current goals: open the adapter file and inspect the `goals.objectives` array, or use
|
|
105
|
+
`pnpm exec elevasis-sdk knowledge:cat goals` (external project).
|
|
106
|
+
|
|
107
|
+
## Write path
|
|
108
|
+
|
|
109
|
+
To add, edit, remove, or update progress on a goal, the `/knowledge` skill runs the codify
|
|
110
|
+
ceremony (`operations/codify-level-a.md`): snapshot → propose → confirm → write → typecheck →
|
|
111
|
+
Zod parse → rollback on failure. Only the `objectives` array is written; no other keys in the
|
|
112
|
+
adapter are touched. For progress-only updates (changing `currentValue` on an existing outcome),
|
|
113
|
+
a targeted edit is preferred over rewriting the entire goals block.
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
**Read via `/knowledge`** — natural-language queries like "what are our goals this quarter?" or
|
|
118
|
+
"what's the current MRR against target?" route to this domain via the skill's intent classifier.
|