@unified-product-graph/cli 0.6.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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +247 -0
- package/dist/cli.cjs +141010 -0
- package/package.json +65 -0
- package/skills/README.md +10 -0
- package/skills/upg/SKILL.md +245 -0
- package/skills/upg-analytics/SKILL.md +135 -0
- package/skills/upg-capture/SKILL.md +274 -0
- package/skills/upg-connect/SKILL.md +167 -0
- package/skills/upg-context/SKILL.md +506 -0
- package/skills/upg-context-intelligence/SKILL.md +227 -0
- package/skills/upg-design-system/SKILL.md +265 -0
- package/skills/upg-diff/SKILL.md +150 -0
- package/skills/upg-discover/SKILL.md +290 -0
- package/skills/upg-explore/SKILL-DETAIL.md +481 -0
- package/skills/upg-explore/SKILL.md +297 -0
- package/skills/upg-export/SKILL.md +385 -0
- package/skills/upg-feedback/SKILL.md +141 -0
- package/skills/upg-gaps/SKILL.md +376 -0
- package/skills/upg-hypothesis/SKILL.md +190 -0
- package/skills/upg-impact/SKILL.md +229 -0
- package/skills/upg-import/SKILL.md +189 -0
- package/skills/upg-init/SKILL.md +410 -0
- package/skills/upg-inspect/SKILL.md +167 -0
- package/skills/upg-journey/SKILL.md +207 -0
- package/skills/upg-launch/SKILL-DETAIL.md +392 -0
- package/skills/upg-launch/SKILL.md +141 -0
- package/skills/upg-migrate/SKILL.md +146 -0
- package/skills/upg-okr/SKILL-DETAIL.md +351 -0
- package/skills/upg-okr/SKILL.md +88 -0
- package/skills/upg-persona/SKILL.md +230 -0
- package/skills/upg-prioritise/SKILL.md +195 -0
- package/skills/upg-pull/SKILL-DETAIL.md +398 -0
- package/skills/upg-pull/SKILL.md +57 -0
- package/skills/upg-push/SKILL-DETAIL.md +385 -0
- package/skills/upg-push/SKILL.md +113 -0
- package/skills/upg-reflect/SKILL.md +201 -0
- package/skills/upg-research/SKILL.md +336 -0
- package/skills/upg-rollback/SKILL.md +163 -0
- package/skills/upg-run/SKILL.md +126 -0
- package/skills/upg-schema-changelog/SKILL.md +231 -0
- package/skills/upg-schema-consolidate/SKILL.md +243 -0
- package/skills/upg-schema-edges/SKILL.md +287 -0
- package/skills/upg-schema-evolve/SKILL.md +313 -0
- package/skills/upg-schema-health/SKILL.md +279 -0
- package/skills/upg-schema-update/SKILL.md +206 -0
- package/skills/upg-snapshot/SKILL.md +108 -0
- package/skills/upg-status/SKILL.md +340 -0
- package/skills/upg-strategy/SKILL.md +334 -0
- package/skills/upg-template/SKILL.md +145 -0
- package/skills/upg-trace/SKILL.md +197 -0
- package/skills/upg-tree/SKILL.md +233 -0
- package/skills/upg-verify/SKILL.md +223 -0
- package/skills/upg-workspace/SKILL.md +103 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upg-schema-health
|
|
3
|
+
description: "Schema usage audit — dead types, empty properties, orphan patterns, real vs theoretical"
|
|
4
|
+
user-invocable: false
|
|
5
|
+
audience: advanced
|
|
6
|
+
argument-hint: "[path to .upg file] or [domain]"
|
|
7
|
+
category: schema
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
> ⚠️ **Advanced skill** — intended for UPG contributors and power users who understand the spec internals. Not for general use. Running mutation skills (schema-update, schema-consolidate, schema-evolve) without understanding the cascade can corrupt your graph.
|
|
11
|
+
|
|
12
|
+
# /upg-schema-health — Schema Usage Audit
|
|
13
|
+
|
|
14
|
+
You are a schema health auditor. Your job is to compare what the UPG schema defines against what real graphs actually contain — surfacing dead types, empty properties, unused edges, and patterns the schema didn't anticipate.
|
|
15
|
+
|
|
16
|
+
**This is the feedback loop for schema governance.** Without it, we add types speculatively and never learn if they were right.
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- After adding new entity types — are they being used?
|
|
21
|
+
- Before a major schema evolution — what's dead weight?
|
|
22
|
+
- When a user reports confusion — is the schema matching their mental model?
|
|
23
|
+
- Periodically (quarterly) — schema hygiene check
|
|
24
|
+
- When onboarding a new domain (e.g., Felix bringing engineering) — what does their graph actually contain?
|
|
25
|
+
|
|
26
|
+
## Input Modes
|
|
27
|
+
|
|
28
|
+
**Mode 1: Audit a specific graph**
|
|
29
|
+
```
|
|
30
|
+
/upg-schema-health .upg/entopo.upg
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**Mode 2: Audit all graphs in workspace**
|
|
34
|
+
```
|
|
35
|
+
/upg-schema-health
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Mode 3: Audit a specific domain against real data**
|
|
39
|
+
```
|
|
40
|
+
/upg-schema-health engineering
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Phase 1: Gather Data
|
|
44
|
+
|
|
45
|
+
### 1a. Load the Graph(s)
|
|
46
|
+
|
|
47
|
+
Use MCP tools to read the graph:
|
|
48
|
+
```
|
|
49
|
+
get_product_context(include_summary: true)
|
|
50
|
+
get_graph_digest()
|
|
51
|
+
list_nodes({ limit: 200 })
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
If auditing multiple graphs, repeat for each `.upg` file via `list_local_products()` and `switch_product()`.
|
|
55
|
+
|
|
56
|
+
### 1b. Load the Schema
|
|
57
|
+
|
|
58
|
+
Read the schema definition:
|
|
59
|
+
```
|
|
60
|
+
Read packages/upg-spec/src/domains.ts → all domains and their types
|
|
61
|
+
Read packages/upg-spec/src/entity-meta.ts → all registered types with maturity
|
|
62
|
+
Read packages/upg-spec/src/index.ts → all edge types
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Phase 2: Type Usage Analysis
|
|
66
|
+
|
|
67
|
+
### 2a. Used vs Defined
|
|
68
|
+
|
|
69
|
+
Compare types present in the graph against types defined in the schema:
|
|
70
|
+
|
|
71
|
+
```
|
|
72
|
+
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
|
|
73
|
+
TYPE USAGE ANALYSIS
|
|
74
|
+
|
|
75
|
+
Schema defines: 310 entity types (across 36 atomic domains, 10 canonical regions)
|
|
76
|
+
Graph uses: 47 entity types
|
|
77
|
+
Coverage: 21%
|
|
78
|
+
|
|
79
|
+
BY DOMAIN:
|
|
80
|
+
| Domain | Defined | Used | Coverage | Status |
|
|
81
|
+
|--------|---------|------|----------|--------|
|
|
82
|
+
| Strategic | 14 | 8 | 57% | 🟢 Active |
|
|
83
|
+
| User | 6 | 4 | 67% | 🟢 Active |
|
|
84
|
+
| Engineering | 26 | 3 | 12% | 🟡 Sparse |
|
|
85
|
+
| Design | 22 | 0 | 0% | 🔴 Unused |
|
|
86
|
+
| Growth | 9 | 0 | 0% | 🔴 Unused |
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### 2b. Dead Types
|
|
90
|
+
|
|
91
|
+
Types defined in the schema but with zero instances across all audited graphs:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
DEAD TYPES (0 instances in any graph)
|
|
95
|
+
|
|
96
|
+
Engineering (23 of 26 unused):
|
|
97
|
+
⚪ aggregate, domain_entity, value_object, command, read_model,
|
|
98
|
+
queue_topic, build_artifact, integration_pattern, ...
|
|
99
|
+
|
|
100
|
+
Design (22 of 22 unused):
|
|
101
|
+
⚪ user_journey, journey_step, design_question, design_concept, ...
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Classify each dead type:**
|
|
105
|
+
- **Too new** — added recently, hasn't had time to be used (check `since` in entity-meta)
|
|
106
|
+
- **Too specialised** — only relevant at scale-up/enterprise tier (check tier classification)
|
|
107
|
+
- **Wrong abstraction** — the concept exists in the user's world but the type doesn't match their mental model
|
|
108
|
+
- **Genuinely unnecessary** — deprecation candidate
|
|
109
|
+
|
|
110
|
+
### 2c. Surprise Types
|
|
111
|
+
|
|
112
|
+
Types present in the graph that aren't in the schema (via `source_type` or custom type strings):
|
|
113
|
+
|
|
114
|
+
```
|
|
115
|
+
SURPRISE TYPES (in graph but not in schema)
|
|
116
|
+
|
|
117
|
+
| Type String | Count | Source | Interpretation |
|
|
118
|
+
|-------------|-------|--------|----------------|
|
|
119
|
+
| "user_segment" | 3 | manual | → Should map to 'market_segment' or 'behavioral_segment' |
|
|
120
|
+
| "tech_spike" | 2 | upg-capture | → Candidate for new type? Or map to 'investigation'? |
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
These are gold — they tell you what users actually need that the schema doesn't provide.
|
|
124
|
+
|
|
125
|
+
## Phase 3: Property Usage Analysis
|
|
126
|
+
|
|
127
|
+
### 3a. Property Fill Rates
|
|
128
|
+
|
|
129
|
+
For each type that has instances, check how many of its defined properties are actually populated:
|
|
130
|
+
|
|
131
|
+
```
|
|
132
|
+
PROPERTY FILL RATES
|
|
133
|
+
|
|
134
|
+
| Type | Instances | Avg Properties Filled | Empty Properties |
|
|
135
|
+
|------|-----------|----------------------|------------------|
|
|
136
|
+
| persona | 5 | 8/12 (67%) | segment, recruit_source, consent_status, switching_costs |
|
|
137
|
+
| hypothesis | 8 | 3/7 (43%) | expected_outcome, timeframe, success_criteria, null_hypothesis |
|
|
138
|
+
| service | 3 | 2/8 (25%) | tech_stack, repo_url, ci_status, health_check, team_owner, status |
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**Flag types with <30% fill rate** — the properties might be:
|
|
142
|
+
- Too granular for the user's stage
|
|
143
|
+
- Named confusingly (user doesn't recognise the field)
|
|
144
|
+
- Better suited as optional future enrichment than required at creation
|
|
145
|
+
|
|
146
|
+
### 3b. Properties Used But Not Defined
|
|
147
|
+
|
|
148
|
+
Check for properties in graph nodes that aren't in the schema's property interface:
|
|
149
|
+
|
|
150
|
+
```
|
|
151
|
+
UNSCHEMATISED PROPERTIES
|
|
152
|
+
|
|
153
|
+
| Type | Property | Count | Values Seen |
|
|
154
|
+
|------|----------|-------|-------------|
|
|
155
|
+
| feature | "priority" | 12 | "high", "medium", "low" |
|
|
156
|
+
| bug | "browser" | 4 | "chrome", "firefox", "safari" |
|
|
157
|
+
| persona | "company_size" | 3 | "startup", "enterprise" |
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
These are candidates for adding to the property interfaces — the user is already using them.
|
|
161
|
+
|
|
162
|
+
## Phase 4: Edge Usage Analysis
|
|
163
|
+
|
|
164
|
+
### 4a. Used vs Defined Edges
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
EDGE USAGE
|
|
168
|
+
|
|
169
|
+
Schema defines: 800+ edge types
|
|
170
|
+
Graph uses: 23 edge types
|
|
171
|
+
Coverage: 3%
|
|
172
|
+
|
|
173
|
+
MOST USED EDGES:
|
|
174
|
+
| Edge Type | Count | Between |
|
|
175
|
+
|-----------|-------|---------|
|
|
176
|
+
| persona_pursues_job | 15 | persona → job |
|
|
177
|
+
| job_has_need | 12 | job → need |
|
|
178
|
+
| feature_has_epic | 8 | feature → epic |
|
|
179
|
+
|
|
180
|
+
NEVER-USED EDGES (in defined domains that ARE used):
|
|
181
|
+
| Edge Type | Source Domain | Target Domain | Status |
|
|
182
|
+
|-----------|-------------|---------------|--------|
|
|
183
|
+
| evidence_supports_hypothesis | validation | validation | ⚪ Available but unused |
|
|
184
|
+
| insight_informs_opportunity | ux_research | discovery | ⚪ Available but unused |
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### 4b. Implicit Relationships
|
|
188
|
+
|
|
189
|
+
Look for nodes that are semantically related but not connected by edges. These suggest missing edges or edges the user doesn't know about:
|
|
190
|
+
|
|
191
|
+
```
|
|
192
|
+
IMPLICIT RELATIONSHIPS (nodes likely related but unconnected)
|
|
193
|
+
|
|
194
|
+
| Node A | Node B | Why related | Missing edge? |
|
|
195
|
+
|--------|--------|-------------|--------------|
|
|
196
|
+
| "Auth redesign" (feature) | "OAuth migration" (tech_debt) | Same domain keywords | debt_blocks_feature? |
|
|
197
|
+
| "Mobile persona" (persona) | "App Store channel" (acquisition_channel) | channel_targets_persona? |
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Phase 5: Structural Health
|
|
201
|
+
|
|
202
|
+
### 5a. Orphan Rate by Type
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
ORPHAN ANALYSIS
|
|
206
|
+
|
|
207
|
+
| Type | Total | Orphaned | Orphan Rate | Concern |
|
|
208
|
+
|------|-------|----------|-------------|---------|
|
|
209
|
+
| feature | 12 | 2 | 17% | 🟡 2 features with no parent or children |
|
|
210
|
+
| hypothesis | 8 | 5 | 63% | 🔴 Most hypotheses disconnected |
|
|
211
|
+
| task | 6 | 6 | 100% | 🔴 All tasks are orphans — wrong parent? |
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
**High orphan rates suggest:**
|
|
215
|
+
- Parent-child hierarchy doesn't match user's mental model
|
|
216
|
+
- The creation flow (skill) doesn't prompt for connections
|
|
217
|
+
- The type is being used as a standalone note, not a graph entity
|
|
218
|
+
|
|
219
|
+
### 5b. Chain Completeness
|
|
220
|
+
|
|
221
|
+
Check the key chains that make the graph useful:
|
|
222
|
+
|
|
223
|
+
```
|
|
224
|
+
CHAIN HEALTH
|
|
225
|
+
|
|
226
|
+
persona → job → need → opportunity → solution → hypothesis → experiment → learning
|
|
227
|
+
5/5 4/5 3/5 2/5 1/5 1/5 0/5 0/5
|
|
228
|
+
|
|
229
|
+
Chain breaks at: opportunity → solution (only 1 of 2 opportunities has solutions)
|
|
230
|
+
Chain dies at: experiment (no experiments exist)
|
|
231
|
+
|
|
232
|
+
→ Discovery is strong, validation is absent
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Phase 6: Recommendations
|
|
236
|
+
|
|
237
|
+
Synthesise findings into actionable recommendations:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
|
|
241
|
+
SCHEMA HEALTH SUMMARY
|
|
242
|
+
|
|
243
|
+
Graph: [name] · [N] nodes · [M] edges · [T] types used
|
|
244
|
+
|
|
245
|
+
🟢 HEALTHY
|
|
246
|
+
- [list what's working well]
|
|
247
|
+
|
|
248
|
+
🟡 ATTENTION
|
|
249
|
+
- [list things that need review]
|
|
250
|
+
|
|
251
|
+
🔴 ACTION NEEDED
|
|
252
|
+
- [list things that need fixing]
|
|
253
|
+
|
|
254
|
+
RECOMMENDATIONS:
|
|
255
|
+
1. [Most impactful action] — /upg-schema-evolve [domain]
|
|
256
|
+
2. [Second action] — /upg-schema-consolidate [types]
|
|
257
|
+
3. [Third action] — consider deprecating [types]
|
|
258
|
+
|
|
259
|
+
DEAD TYPE CANDIDATES FOR DEPRECATION:
|
|
260
|
+
- [types with 0 usage across all audited graphs AND >6 months old]
|
|
261
|
+
|
|
262
|
+
PROPERTY ENRICHMENT CANDIDATES:
|
|
263
|
+
- [unschematised properties that appear in >3 instances]
|
|
264
|
+
|
|
265
|
+
SURPRISE TYPES TO INVESTIGATE:
|
|
266
|
+
- [custom types that might warrant schema addition]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Key Principles
|
|
270
|
+
|
|
271
|
+
- **Real data over theory.** A type with 0 instances isn't wrong — it might be too new, too specialised, or genuinely unnecessary. The data tells you which.
|
|
272
|
+
- **Surprise types are the most valuable signal.** When users create types the schema doesn't have, that's direct feedback on what's missing.
|
|
273
|
+
- **Property fill rates reveal UX problems.** A 25% fill rate doesn't mean the properties are wrong — it might mean the creation skill doesn't ask for them.
|
|
274
|
+
- **Orphan rate reveals hierarchy problems.** 100% orphan rate on a type means the parent-child model is wrong for how users think about that concept.
|
|
275
|
+
- **Run this before and after schema changes.** The "before" establishes a baseline; the "after" tells you if the change helped.
|
|
276
|
+
- **Cross-graph analysis is more valuable than single-graph.** One graph's habits aren't representative. Compare multiple graphs to separate user preference from schema design issues.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
Internal development skill for UPG schema governance.
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upg-schema-update
|
|
3
|
+
description: "Add or update UPG entity types, edge types, or properties — cascades through the full codebase"
|
|
4
|
+
user-invocable: false
|
|
5
|
+
audience: advanced
|
|
6
|
+
argument-hint: "[entity type name or description of change]"
|
|
7
|
+
category: schema
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
> ⚠️ **Advanced skill** — intended for UPG contributors and power users who understand the spec internals. Not for general use. Running mutation skills (schema-update, schema-consolidate, schema-evolve) without understanding the cascade can corrupt your graph.
|
|
11
|
+
|
|
12
|
+
# /upg-schema-update — UPG Schema Update Cascade
|
|
13
|
+
|
|
14
|
+
You are a schema update operator. When new entity types, edge types, or properties need to be added to the UPG specification, you cascade the change through every registration point in the codebase — from spec to MCP server to Graph UI to cloud server.
|
|
15
|
+
|
|
16
|
+
**This is an internal development skill, not a user-facing UPG skill.**
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
- Adding new entity types (e.g., `investigation`, `root_cause`)
|
|
21
|
+
- Adding new edge types (e.g., `causes`, `revealed_by`)
|
|
22
|
+
- Adding property interfaces to existing types
|
|
23
|
+
- Updating domain groupings
|
|
24
|
+
- Deprecating or renaming entity types
|
|
25
|
+
|
|
26
|
+
## The Cascade
|
|
27
|
+
|
|
28
|
+
Every schema change must flow through these 5 layers in order. **Do not skip layers.** Check each one even if you think it doesn't apply.
|
|
29
|
+
|
|
30
|
+
### Layer 1: `@unified-product-graph/core` (packages/upg-spec/src/)
|
|
31
|
+
|
|
32
|
+
The source of truth. All changes start here.
|
|
33
|
+
|
|
34
|
+
| File | What to update | How to find the insertion point |
|
|
35
|
+
|------|---------------|-------------------------------|
|
|
36
|
+
| `catalog/entity-catalog.ts` | Add to `UPGEntityType` union | Find the domain comment (e.g., `// Engineering`) and add after the last type in that section |
|
|
37
|
+
| `registry/entity-meta.ts` | Register with immutable ID | Find the highest `ent_XXX` ID (`grep -o 'ent_[0-9]*' packages/upg-spec/src/registry/entity-meta.ts \| sort -t_ -k2 -n \| tail -1`), increment by 1. Set `maturity: 'stable'`, `since: '0.2.0'` |
|
|
38
|
+
| `registry/domains.ts` | Add to domain's `types` array | Find the domain by `id` in `UPG_DOMAINS`, add to its `types` array |
|
|
39
|
+
| `properties/domains/<domain>.ts` | Add property interface | Create `export interface XxxProperties { ... }` with typed fields. Use existing interfaces as templates. |
|
|
40
|
+
| `catalog/edge-catalog.ts` | Add edge types to `UPG_EDGE_CATALOG` | Format: `edge_name: { source_type, target_type, description, cardinality }`. The `UPG_EDGE_PAIR_MAP` is derived automatically. |
|
|
41
|
+
| `shapes/edges.ts` / `shapes/base-node.ts` | If modifying UPGEdge / UPGBaseNode | Rarely needed — most additions go in catalog and property interfaces |
|
|
42
|
+
|
|
43
|
+
**Verify:** `cd packages/upg-spec && npm run build` — must compile clean.
|
|
44
|
+
|
|
45
|
+
### Layer 2: `upg-mcp-server` (packages/upg-mcp-server/)
|
|
46
|
+
|
|
47
|
+
The MCP server that reads/writes `.upg` files.
|
|
48
|
+
|
|
49
|
+
| What to check | When it matters |
|
|
50
|
+
|---------------|----------------|
|
|
51
|
+
| `src/server.ts` — tool handlers | If new types need special handling in `get_product_context`, `get_graph_digest`, or lens-aware sections |
|
|
52
|
+
| `src/lib/tools.ts` — digest computation | If new types should appear in health metrics |
|
|
53
|
+
| `skills/` — skill markdown files | If any skill references entity types that changed |
|
|
54
|
+
| `src/lib/edge-inference.ts` | If new edge types need inference rules |
|
|
55
|
+
| `src/classification.ts` | If tier classification changes |
|
|
56
|
+
|
|
57
|
+
**Verify:** `cd packages/upg-mcp-server && npm run build` — JS must build (DTS error in preflight.ts is pre-existing, ignore it).
|
|
58
|
+
|
|
59
|
+
### Layer 3: `apps/graph` (apps/graph/src/)
|
|
60
|
+
|
|
61
|
+
The Graph UI. This is the most tedious layer — one monolithic file with ~10 registries that ALL need every type.
|
|
62
|
+
|
|
63
|
+
**Main file:** `apps/graph/src/lib/entity-metadata.ts` (~6300 lines)
|
|
64
|
+
|
|
65
|
+
**EVERY new NodeType requires entries in ALL of these registries:**
|
|
66
|
+
|
|
67
|
+
| Registry | Type | Line range | Format |
|
|
68
|
+
|----------|------|------------|--------|
|
|
69
|
+
| `NodeType` (in `types/graph.ts`) | Union type | ~138–550 | `\| 'type_name' // phase: X` |
|
|
70
|
+
| `NODE_LABELS` | `Record<NodeType, string>` | ~70–435 | `type_name: 'Display Name',` |
|
|
71
|
+
| `NODE_LABELS_PLURAL` | `Record<NodeType, string>` | ~436–800 | `type_name: 'Display Names',` |
|
|
72
|
+
| `NODE_ICONS` | `Record<NodeType, string>` | ~801–935 | `type_name: '🔍',` |
|
|
73
|
+
| `NODE_DESCRIPTIONS` | `Record<NodeType, string>` | ~1166–1530 | `type_name: 'One-line description',` |
|
|
74
|
+
| `NODE_LAYER` | `Record<NodeType, string>` | ~1531–1895 | `type_name: 'Engineering',` |
|
|
75
|
+
| `NODE_TYPE_TO_SLUG` | `Record<NodeType, string>` | ~2351–2715 | `type_name: 'type-name',` |
|
|
76
|
+
| `ENTITY_LAYERS` | Domain grouping | ~3547–3582 | Add to the right domain array |
|
|
77
|
+
| `DEFAULT_LAYOUT` | Layout mode | ~3600–3973 | `type_name: 'default',` |
|
|
78
|
+
| `PARENT_TYPE_MAP` | `Partial<Record<NodeType, NodeType>>` | ~6135–6330 | `type_name: 'parent_type',` |
|
|
79
|
+
|
|
80
|
+
**Optional registries (add if applicable):**
|
|
81
|
+
|
|
82
|
+
| Registry | When |
|
|
83
|
+
|----------|------|
|
|
84
|
+
| `TOP_LEVEL_TYPES` (~6065) | If the type can be a root node (no required parent) |
|
|
85
|
+
| `BOARD_GROUP_OPTIONS` (~3974) | If the type should have board view grouping |
|
|
86
|
+
| `VALID_CHILDREN` (if exists) | For explicit child-type allowlists |
|
|
87
|
+
|
|
88
|
+
**How to add to entity-metadata.ts efficiently:**
|
|
89
|
+
|
|
90
|
+
1. Search for an existing type in the same domain to use as a template
|
|
91
|
+
2. For each registry, search for that template type and add the new type nearby
|
|
92
|
+
3. Follow alphabetical or domain ordering within each registry
|
|
93
|
+
|
|
94
|
+
**Verify:** `cd apps/graph && npx tsc --noEmit` — the `Record<NodeType, ...>` pattern will catch any missing entries at compile time.
|
|
95
|
+
|
|
96
|
+
### Layer 4: `upg-cloud-server` (packages/upg-cloud-server/)
|
|
97
|
+
|
|
98
|
+
The cloud API server with PostgreSQL storage.
|
|
99
|
+
|
|
100
|
+
| What to check | When it matters |
|
|
101
|
+
|---------------|----------------|
|
|
102
|
+
| `src/store/pg-store.ts` — `rowToEdge()` | If new fields were added to UPGEdge (e.g., `confidence`, `note`) — need column or JSONB field |
|
|
103
|
+
| `src/store/pg-store.ts` — `rowToNode()` | If new fields were added to UPGBaseNode |
|
|
104
|
+
| Database migrations | If new columns needed for new edge/node properties |
|
|
105
|
+
|
|
106
|
+
**Usually no changes needed** for additive entity types — the cloud server stores types as strings and properties as JSONB. But check edge/node serialisation if interface shapes changed.
|
|
107
|
+
|
|
108
|
+
### Layer 5: `apps/upg-site` (apps/upg-site/)
|
|
109
|
+
|
|
110
|
+
The documentation site.
|
|
111
|
+
|
|
112
|
+
| What to check | When it matters |
|
|
113
|
+
|---------------|----------------|
|
|
114
|
+
| Entity type documentation pages | If new types need user-facing docs |
|
|
115
|
+
| Sanity CMS content | If framework docs reference entity types |
|
|
116
|
+
| Domain/layer overview pages | If domain composition changed |
|
|
117
|
+
|
|
118
|
+
**Usually deferred** — docs update is a separate task.
|
|
119
|
+
|
|
120
|
+
## Workflow
|
|
121
|
+
|
|
122
|
+
### Step 1: Gather Requirements
|
|
123
|
+
|
|
124
|
+
Ask for or determine:
|
|
125
|
+
- **Entity type name(s)** — snake_case, singular (e.g., `root_cause`)
|
|
126
|
+
- **Domain** — which domain does it belong to? (e.g., `engineering`)
|
|
127
|
+
- **Properties** — what typed fields does it have?
|
|
128
|
+
- **Parent type** — what's its canonical parent in the hierarchy?
|
|
129
|
+
- **Edge types** — what relationships does it have with other types?
|
|
130
|
+
- **Display metadata** — label, plural, icon, description, layer name
|
|
131
|
+
|
|
132
|
+
### Step 2: Execute the Cascade
|
|
133
|
+
|
|
134
|
+
Work through Layers 1–5 in order. For each layer:
|
|
135
|
+
1. Read the relevant files
|
|
136
|
+
2. Find the insertion points
|
|
137
|
+
3. Make the changes
|
|
138
|
+
4. Verify the build
|
|
139
|
+
|
|
140
|
+
### Step 3: Verify
|
|
141
|
+
|
|
142
|
+
Run these checks after all changes:
|
|
143
|
+
```bash
|
|
144
|
+
# Layer 1
|
|
145
|
+
cd packages/upg-spec && npm run build
|
|
146
|
+
|
|
147
|
+
# Layer 2
|
|
148
|
+
cd packages/upg-mcp-server && npm run build
|
|
149
|
+
|
|
150
|
+
# Layer 3 (most likely to catch missing entries)
|
|
151
|
+
cd apps/graph && npx tsc --noEmit
|
|
152
|
+
|
|
153
|
+
# Layer 4 (if changed)
|
|
154
|
+
cd packages/upg-cloud-server && npm run build
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**The `Record<NodeType, ...>` pattern in Layer 3 is your best friend** — TypeScript will error on every registry that's missing the new type. Let the compiler find what you missed.
|
|
158
|
+
|
|
159
|
+
### Step 4: Commit
|
|
160
|
+
|
|
161
|
+
Use a commit message like:
|
|
162
|
+
```
|
|
163
|
+
feat(upg-spec): add <type_name> entity type to <domain> domain
|
|
164
|
+
|
|
165
|
+
Cascade: spec → mcp-server → graph → cloud-server
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## ID Assignment Rules
|
|
169
|
+
|
|
170
|
+
- Entity type IDs are immutable and sequential: `ent_001`, `ent_002`, ...
|
|
171
|
+
- Always find the current highest: `grep -o 'ent_[0-9]*' packages/upg-spec/src/registry/entity-meta.ts | sort -t_ -k2 -n | tail -1`
|
|
172
|
+
- Increment by 1 for each new type
|
|
173
|
+
- **Never reuse an ID**, even if the previous type was deprecated
|
|
174
|
+
|
|
175
|
+
## Edge Type Rules
|
|
176
|
+
|
|
177
|
+
- Edges live in `UPG_EDGE_CATALOG` in `catalog/edge-catalog.ts`
|
|
178
|
+
- Format: `edge_name: { source_type, target_type, description, cardinality }`
|
|
179
|
+
- `UPG_EDGE_PAIR_MAP` (`source_type:target_type` → edge key) is derived automatically — don't edit it
|
|
180
|
+
- Check for duplicates before adding: search for the pair in the catalog
|
|
181
|
+
- Edge names should be verb-based: `causes`, `blocks`, `enables`, `implements`, `specifies`
|
|
182
|
+
|
|
183
|
+
## Common Patterns
|
|
184
|
+
|
|
185
|
+
**Adding a debugging/troubleshooting entity (like investigation, root_cause):**
|
|
186
|
+
- Domain: `engineering`
|
|
187
|
+
- Parent: usually `service` or `bounded_context`
|
|
188
|
+
- Edges: `causes`, `affects`, `revealed_by`
|
|
189
|
+
- Properties: `status`, `severity`, `category`
|
|
190
|
+
|
|
191
|
+
**Adding a design governance entity:**
|
|
192
|
+
- For design decisions specifically, use the consolidated `decision` type with `layer: "design"` (see v0.2.0 migration) rather than creating a new type.
|
|
193
|
+
- Domain: `design`
|
|
194
|
+
- Parent: usually `product` or `design_system`
|
|
195
|
+
- Edges: `decision_informs_decision`, `decision_affects_component`, `decision_affects_screen`
|
|
196
|
+
- Properties (DecisionProperties): `layer`, `status` (proposed/accepted/deprecated/superseded), `context`, `decision`, `consequences`
|
|
197
|
+
|
|
198
|
+
**Adding a growth/marketing entity:**
|
|
199
|
+
- Domain: `growth` or `go_to_market`
|
|
200
|
+
- Parent: varies
|
|
201
|
+
- Edges: `targets`, `feeds`, `measures`
|
|
202
|
+
- Properties: domain-specific metrics
|
|
203
|
+
|
|
204
|
+
## Key Principle
|
|
205
|
+
|
|
206
|
+
**The compiler is the checklist.** After adding to Layer 1 (spec) and Layer 3 (graph), run `tsc --noEmit` on `apps/graph`. Every `Record<NodeType, ...>` will error if you missed a registration. Fix each error = complete cascade.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: upg-snapshot
|
|
3
|
+
description: "Save a named checkpoint of your product graph — version your thinking"
|
|
4
|
+
user-invocable: true
|
|
5
|
+
argument-hint: "[message]"
|
|
6
|
+
category: tooling
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# /upg-snapshot — Version Your Thinking
|
|
10
|
+
|
|
11
|
+
You are a Unified Product Graph versioning tool. Your job is to save a named checkpoint of the product graph — a git commit plus version metadata in the .upg file. Fast, no questions beyond the message.
|
|
12
|
+
|
|
13
|
+
**Before producing any output, read the design system:** /upg-context for emoji mappings, formatting rules, and shared interaction patterns.
|
|
14
|
+
|
|
15
|
+
## Tools
|
|
16
|
+
|
|
17
|
+
Use `mcp__unified-product-graph__get_graph_digest` to read current graph state.
|
|
18
|
+
Use Bash for git operations and .upg file version patching.
|
|
19
|
+
|
|
20
|
+
## Flow
|
|
21
|
+
|
|
22
|
+
### Step 1: Read Graph State
|
|
23
|
+
|
|
24
|
+
Silently fetch the graph summary:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
get_graph_digest()
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Extract: product title, node count, edge count.
|
|
31
|
+
|
|
32
|
+
### Step 2: Get Snapshot Message
|
|
33
|
+
|
|
34
|
+
If the user provided a message as an argument, use it directly.
|
|
35
|
+
|
|
36
|
+
If no message was provided, ask once:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
What changed? (e.g. "Added pricing strategy", "Refined personas")
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Do NOT ask anything else. One question max.
|
|
43
|
+
|
|
44
|
+
### Step 3: Increment Version
|
|
45
|
+
|
|
46
|
+
Read the .upg file with Bash, extract the current `graph_version` (default to 0 if missing), increment by 1, and write it back:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Read current version from .upg JSON
|
|
50
|
+
current=$(python3 -c "import json; d=json.load(open('$(ls *.upg | head -1)')); print(d.get('graph_version', 0))")
|
|
51
|
+
next=$((current + 1))
|
|
52
|
+
|
|
53
|
+
# Patch graph_version into the .upg JSON
|
|
54
|
+
python3 -c "
|
|
55
|
+
import json, glob
|
|
56
|
+
f = glob.glob('*.upg')[0]
|
|
57
|
+
d = json.load(open(f))
|
|
58
|
+
d['graph_version'] = $next
|
|
59
|
+
json.dump(d, open(f, 'w'), indent=2)
|
|
60
|
+
print(f' patched {f} → version {next}')
|
|
61
|
+
"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Step 4: Git Commit
|
|
65
|
+
|
|
66
|
+
Stage and commit the .upg file:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
git add *.upg
|
|
70
|
+
git commit -m "upg: <message>"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
If git fails (not a repo, nothing to commit), report the error briefly and still confirm the version was incremented in the file.
|
|
74
|
+
|
|
75
|
+
### Step 5: Confirm
|
|
76
|
+
|
|
77
|
+
Show confirmation using this exact format:
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
<checkmark> Snapshot saved — version <N>: "<message>"
|
|
81
|
+
<node_count> entities · <edge_count> edges
|
|
82
|
+
|
|
83
|
+
Rollback: git checkout HEAD~1 -- <filename>.upg
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Use the checkmark symbol, entity/edge counts from Step 1, and the actual .upg filename.
|
|
87
|
+
|
|
88
|
+
## Example Output
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
✓ Snapshot saved — version 5: "Added pricing strategy"
|
|
92
|
+
47 entities · 38 edges
|
|
93
|
+
|
|
94
|
+
Rollback: git checkout HEAD~1 -- product.upg
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Key Principles
|
|
98
|
+
|
|
99
|
+
- **Fast.** No preamble, no dashboard, no health check. ~10 seconds.
|
|
100
|
+
- **One question max.** Only ask for the message if not provided.
|
|
101
|
+
- **Git-native.** The .upg file is diffable — git is the version history.
|
|
102
|
+
- **Silent on success.** Don't explain what versioning is. Just confirm.
|
|
103
|
+
- **Graceful on failure.** If git isn't available, still patch the version and say so.
|
|
104
|
+
- **No graph entity mutations.** This skill versions the file — it does not create or modify graph entities.
|
|
105
|
+
|
|
106
|
+
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
|
|
107
|
+
Your `.upg` file is yours — open standard, portable, git-friendly.
|
|
108
|
+
unifiedproductgraph.org
|