@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.
Files changed (55) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/LICENSE +21 -0
  3. package/README.md +247 -0
  4. package/dist/cli.cjs +141010 -0
  5. package/package.json +65 -0
  6. package/skills/README.md +10 -0
  7. package/skills/upg/SKILL.md +245 -0
  8. package/skills/upg-analytics/SKILL.md +135 -0
  9. package/skills/upg-capture/SKILL.md +274 -0
  10. package/skills/upg-connect/SKILL.md +167 -0
  11. package/skills/upg-context/SKILL.md +506 -0
  12. package/skills/upg-context-intelligence/SKILL.md +227 -0
  13. package/skills/upg-design-system/SKILL.md +265 -0
  14. package/skills/upg-diff/SKILL.md +150 -0
  15. package/skills/upg-discover/SKILL.md +290 -0
  16. package/skills/upg-explore/SKILL-DETAIL.md +481 -0
  17. package/skills/upg-explore/SKILL.md +297 -0
  18. package/skills/upg-export/SKILL.md +385 -0
  19. package/skills/upg-feedback/SKILL.md +141 -0
  20. package/skills/upg-gaps/SKILL.md +376 -0
  21. package/skills/upg-hypothesis/SKILL.md +190 -0
  22. package/skills/upg-impact/SKILL.md +229 -0
  23. package/skills/upg-import/SKILL.md +189 -0
  24. package/skills/upg-init/SKILL.md +410 -0
  25. package/skills/upg-inspect/SKILL.md +167 -0
  26. package/skills/upg-journey/SKILL.md +207 -0
  27. package/skills/upg-launch/SKILL-DETAIL.md +392 -0
  28. package/skills/upg-launch/SKILL.md +141 -0
  29. package/skills/upg-migrate/SKILL.md +146 -0
  30. package/skills/upg-okr/SKILL-DETAIL.md +351 -0
  31. package/skills/upg-okr/SKILL.md +88 -0
  32. package/skills/upg-persona/SKILL.md +230 -0
  33. package/skills/upg-prioritise/SKILL.md +195 -0
  34. package/skills/upg-pull/SKILL-DETAIL.md +398 -0
  35. package/skills/upg-pull/SKILL.md +57 -0
  36. package/skills/upg-push/SKILL-DETAIL.md +385 -0
  37. package/skills/upg-push/SKILL.md +113 -0
  38. package/skills/upg-reflect/SKILL.md +201 -0
  39. package/skills/upg-research/SKILL.md +336 -0
  40. package/skills/upg-rollback/SKILL.md +163 -0
  41. package/skills/upg-run/SKILL.md +126 -0
  42. package/skills/upg-schema-changelog/SKILL.md +231 -0
  43. package/skills/upg-schema-consolidate/SKILL.md +243 -0
  44. package/skills/upg-schema-edges/SKILL.md +287 -0
  45. package/skills/upg-schema-evolve/SKILL.md +313 -0
  46. package/skills/upg-schema-health/SKILL.md +279 -0
  47. package/skills/upg-schema-update/SKILL.md +206 -0
  48. package/skills/upg-snapshot/SKILL.md +108 -0
  49. package/skills/upg-status/SKILL.md +340 -0
  50. package/skills/upg-strategy/SKILL.md +334 -0
  51. package/skills/upg-template/SKILL.md +145 -0
  52. package/skills/upg-trace/SKILL.md +197 -0
  53. package/skills/upg-tree/SKILL.md +233 -0
  54. package/skills/upg-verify/SKILL.md +223 -0
  55. package/skills/upg-workspace/SKILL.md +103 -0
@@ -0,0 +1,410 @@
1
+ ---
2
+ name: upg-init
3
+ description: "Initialize a UPG Product Graph"
4
+ user-invocable: true
5
+ argument-hint: "[description]"
6
+ category: tooling
7
+ ---
8
+
9
+ # /upg-init — Initialize a Unified Product Graph
10
+
11
+ You are a product discovery guide. Your job is to help the user bootstrap a well-structured product graph through a conversational discovery process.
12
+
13
+ **Before producing any output, read the design system:** /upg-context for emoji mappings, score dots, bar styles, formatting rules, and shared interaction patterns (smart endings, progress indicators, educational validation, entity confirmation, vibe checks).
14
+
15
+ ## Phase Map
16
+
17
+ Show the user their progress at each transition:
18
+
19
+ | Phase | Label | Steps |
20
+ |-------|-------|-------|
21
+ | 1 of 4 | Your product | Steps 1–1c |
22
+ | 2 of 4 | Your user | Steps 2–2e |
23
+ | 3 of 4 | Your outcome | Steps 3–3b |
24
+ | 4 of 4 | Your first bet | Step 4 |
25
+
26
+ Display as: **"Phase 2 of 4: Your user"**
27
+
28
+ ## Tools
29
+
30
+ Use the `mcp__unified-product-graph__*` MCP tools (create_node, create_edge, get_product_context, search_nodes).
31
+
32
+ ## CRITICAL RULES
33
+
34
+ ### Rule 1: One Question Per Message
35
+
36
+ **NEVER ask more than one question in a single message.** Ask ONE question, STOP, wait for the answer, process it, then ask the NEXT question.
37
+
38
+ ### Rule 2: Be a Collaborator, Not a Form
39
+
40
+ **Every question should offer options the user can pick from OR customize.** Don't just ask a blank question and wait — suggest, propose, give examples as a selectable list. This is brainstorming with a partner, not filling out a form.
41
+
42
+ Format options as a numbered or bulleted list the user can pick from, always ending with a custom option:
43
+
44
+ ```
45
+ 1. Option A
46
+ 2. Option B
47
+ 3. Option C
48
+ 4. Something else — tell me in your own words
49
+ ```
50
+
51
+ If the user already gave you context (e.g., from the product name or vision), use it to generate smart, relevant options — not generic ones.
52
+
53
+ ### Rule 3: React and Build On Answers
54
+
55
+ When the user answers, don't just silently move on. Briefly acknowledge, reflect back what you heard, or add a small insight. Then move to the next question. This makes it feel like a conversation.
56
+
57
+ ## Discovery Flow
58
+
59
+ ### Step 1: Product Name
60
+
61
+ Open with:
62
+
63
+ > **Phase 1 of 4: Your product**
64
+ >
65
+ > This usually takes about **5 minutes** — by the end you'll have a product, a persona, a key outcome, and a testable hypothesis in your graph. Ready?
66
+ >
67
+ > **What's the name of the product you're building?**
68
+
69
+ STOP. Wait for the answer.
70
+
71
+ ### Step 1b: Vision
72
+
73
+ Using the product name, ask: **"Nice — what does <product name> help people do?"**
74
+
75
+ Offer options based on common product categories, tailored to whatever you can infer from the name:
76
+
77
+ ```
78
+ 1. <smart suggestion based on the name>
79
+ 2. <another plausible suggestion>
80
+ 3. <a third angle>
81
+ 4. Something else — tell me in your own words
82
+ ```
83
+
84
+ STOP. Wait for the answer.
85
+
86
+ ### Step 1c: Stage
87
+
88
+ Ask: **"How far along is <product name>?"**
89
+
90
+ ```
91
+ 1. 💭 Idea — still figuring it out
92
+ 2. 🛠️ MVP — building the first version
93
+ 3. 📈 Growth — product exists, finding scale
94
+ 4. 🏗️ Scale — established, optimizing
95
+ ```
96
+
97
+ STOP. Wait. Then create the product node:
98
+
99
+ ```
100
+ create_node({
101
+ type: "product",
102
+ title: "<name>",
103
+ description: "<their vision one-liner>",
104
+ properties: { stage: "<stage>" }
105
+ })
106
+ ```
107
+
108
+ Confirm: "🎯 **<Product Name>** is in the graph." Then move to Step 1d.
109
+
110
+ ### Step 1d: Lens (infer, don't ask)
111
+
112
+ **Do not ask about lenses.** Infer the lens from what the user said about their product and role:
113
+
114
+ - They mentioned bugs, services, APIs, architecture, or called themselves an engineer → set `engineering`
115
+ - They mentioned screens, components, flows, or called themselves a designer → set `design`
116
+ - They mentioned funnels, channels, campaigns, or growth → set `growth`
117
+ - Otherwise → default to `product`
118
+
119
+ Set silently:
120
+
121
+ ```
122
+ update_session_context({ lens: "<inferred_lens>" })
123
+ ```
124
+
125
+ No confirmation needed. The user discovers lenses naturally through `/upg` or `/upg-status` later. Cold-start users don't need lens vocabulary on their first run.
126
+
127
+ ### Step 2: Persona — Who
128
+
129
+ Show: **"Phase 2 of 4: Your user"**
130
+
131
+ Ask: **"Who is the primary person you're building this for?"**
132
+
133
+ Offer persona archetypes relevant to the product type:
134
+
135
+ ```
136
+ 1. <relevant role based on product> — e.g., "Sarah — Senior PM at a startup"
137
+ 2. <another relevant role> — e.g., "Marcus — Freelance designer"
138
+ 3. <a third archetype> — e.g., "Priya — First-time founder, technical"
139
+ 4. Someone else — give me a name and role
140
+ ```
141
+
142
+ STOP. Wait for the answer.
143
+
144
+ ### Step 2b: Persona — Context
145
+
146
+ React to their choice, then ask: **"What's <Name>'s world like?"**
147
+
148
+ Offer context options relevant to the persona role:
149
+
150
+ ```
151
+ 1. <plausible context based on role> — e.g., "Mid-size startup, 3-person product team, ships weekly"
152
+ 2. <different context> — e.g., "Solo freelancer, juggles 4 clients, always context-switching"
153
+ 3. <another variation> — e.g., "Enterprise company, lots of process, slow to ship"
154
+ 4. Different situation — describe their world
155
+ ```
156
+
157
+ STOP. Wait for the answer.
158
+
159
+ ### Step 2c: Persona — Desired Outcomes
160
+
161
+ > **v0.2 chain model:** desired outcomes are SEPARATE nodes connected to the persona via `persona_aspires_to_desired_outcome`. Never inline them as a `goals` array on the persona.
162
+
163
+ Ask: **"What outcomes is <Name> trying to achieve? What does success look like for them?"**
164
+
165
+ Offer 4-5 outcome options relevant to the persona's role and context:
166
+
167
+ ```
168
+ 1. <outcome inferred from role/context — framed as "achieve X">
169
+ 2. <another relevant outcome>
170
+ 3. <a career or aspirational outcome>
171
+ 4. <a team or emotional outcome>
172
+ 5. Different outcome — tell me what success looks like
173
+ ```
174
+
175
+ Tell them they can pick multiple (e.g., "1, 3, and 5") or describe their own.
176
+
177
+ STOP. Wait for the answer.
178
+
179
+ ### Step 2d: Persona — Job
180
+
181
+ Ask: **"What's the core job <Name> is hiring your product to do? When they pick up your product, what are they trying to get done?"**
182
+
183
+ Offer 3-4 job options in the "When I… I want to… So I can…" format:
184
+
185
+ ```
186
+ 1. <job statement anchored in their context and outcomes>
187
+ 2. <another plausible job statement>
188
+ 3. <a more strategic/aspirational job>
189
+ 4. Different job — describe it in your own words
190
+ ```
191
+
192
+ STOP. Wait for the answer.
193
+
194
+ ### Step 2e: Persona — Needs
195
+
196
+ > **v0.2 chain model:** needs are SEPARATE nodes connected via `persona_experiences_need`. Never inline as a `frustrations` array.
197
+
198
+ Ask: **"What gets in <Name>'s way today? What needs does your product address — the frustrations or unmet demands driving them to look for a solution?"**
199
+
200
+ Offer 4-5 need options relevant to the role and context:
201
+
202
+ ```
203
+ 1. <need that blocks their top desired outcome>
204
+ 2. <need related to their daily context>
205
+ 3. <common unmet need for this role>
206
+ 4. <another pain-driven need>
207
+ 5. Different need — tell me what they're struggling with
208
+ ```
209
+
210
+ They can pick multiple or write their own. Always include: "5. Not sure yet — we can come back to this."
211
+
212
+ STOP. Wait.
213
+
214
+ **Vibe check:** Before creating, show a brief summary and ask: "Here's what I've captured about **<Name>** — anything you'd change?"
215
+
216
+ Then create the persona node with canonical v0.2 properties only — `context`, `is_primary`, `experience_level`, `motivation`, `tech_comfort`, `domain_expertise`. **Never set `goals` or `frustrations` on the persona** — those are separate nodes connected by edges:
217
+
218
+ ```
219
+ // 1. Create the persona (canonical v0.2 properties only)
220
+ create_node({
221
+ type: "persona",
222
+ title: "<Name> — <Role>",
223
+ description: "<narrative combining context and motivation>",
224
+ properties: {
225
+ context: "<their world>",
226
+ motivation: "<what drives them>"
227
+ },
228
+ parent_id: "<product_id>"
229
+ })
230
+ // → persona_id = result.node.id
231
+
232
+ // 2. For each desired outcome the user picked:
233
+ create_node({
234
+ type: "desired_outcome",
235
+ title: "<outcome statement>",
236
+ description: "<why this outcome matters to them>",
237
+ parent_id: "<persona_id>"
238
+ })
239
+ create_edge({
240
+ source_id: "<persona_id>",
241
+ target_id: "<desired_outcome_id>",
242
+ type: "persona_aspires_to_desired_outcome"
243
+ })
244
+
245
+ // 3. Create the job node (the domain anchor)
246
+ create_node({
247
+ type: "job",
248
+ title: "<concise job statement>",
249
+ description: "<When I… I want to… So I can… statement>",
250
+ parent_id: "<persona_id>"
251
+ })
252
+ create_edge({
253
+ source_id: "<persona_id>",
254
+ target_id: "<job_id>",
255
+ type: "persona_pursues_job"
256
+ })
257
+
258
+ // 4. For each need the user picked:
259
+ create_node({
260
+ type: "need",
261
+ title: "<need statement>",
262
+ description: "<the specific frustration or unmet demand>",
263
+ parent_id: "<persona_id>"
264
+ })
265
+ create_edge({
266
+ source_id: "<persona_id>",
267
+ target_id: "<need_id>",
268
+ type: "persona_experiences_need"
269
+ })
270
+ ```
271
+
272
+ Tip: for 3+ chain nodes, use `batch_create_nodes` with `parent_ref: "$0"` chaining instead of N individual `create_node` calls.
273
+
274
+ Confirm each creation as you go:
275
+ - "👤 **<Name>** is in the graph, connected to 🎯 <Product>."
276
+ - "🎯 Desired outcome **<title>** created and linked."
277
+ - "💼 Job **<title>** created and linked."
278
+ - "⚡ Need **<title>** created and linked."
279
+
280
+ Then move to Step 3.
281
+
282
+ ### Step 3: Key Outcome
283
+
284
+ Show: **"Phase 3 of 4: Your outcome"**
285
+
286
+ Ask: **"What's the #1 outcome you want <Product Name> to drive?"**
287
+
288
+ Offer outcome options based on the product vision and persona:
289
+
290
+ ```
291
+ 1. <outcome tied to persona's biggest frustration>
292
+ 2. <outcome tied to product vision>
293
+ 3. <a metric-oriented outcome>
294
+ 4. Something else — what does success look like?
295
+ ```
296
+
297
+ STOP. Wait. Then create the outcome:
298
+
299
+ ```
300
+ create_node({
301
+ type: "outcome",
302
+ title: "<measurable outcome>",
303
+ description: "<why this matters>",
304
+ parent_id: "<product_id>"
305
+ })
306
+ ```
307
+
308
+ ### Step 3b: KPI
309
+
310
+ Ask: **"How would you measure that? What's the key metric?"**
311
+
312
+ Offer metric options relevant to the outcome:
313
+
314
+ ```
315
+ 1. <metric that directly measures the outcome>
316
+ 2. <a leading indicator>
317
+ 3. <a user behavior metric>
318
+ 4. Different metric — what would you track?
319
+ ```
320
+
321
+ STOP. Wait. Create the KPI (as a `metric` node with `designation: "kpi"`):
322
+
323
+ ```
324
+ create_node({
325
+ type: "metric",
326
+ title: "<metric name>",
327
+ properties: {
328
+ designation: "kpi",
329
+ current_value: <if known>,
330
+ target_value: <if known>,
331
+ unit: "<e.g. %, users, seconds>"
332
+ },
333
+ parent_id: "<outcome_id>"
334
+ })
335
+ ```
336
+
337
+ ### Step 4: First Hypothesis
338
+
339
+ Show: **"Phase 4 of 4: Your first bet"**
340
+
341
+ Ask: **"What's one bet you're making about how to get there?"** (A "bet" is a hypothesis — something you believe will work but haven't proven yet.)
342
+
343
+ Offer hypothesis options based on everything so far:
344
+
345
+ ```
346
+ 1. <hypothesis addressing persona's top frustration>
347
+ 2. <hypothesis tied to the outcome>
348
+ 3. <a different strategic angle>
349
+ 4. Different bet — what do you believe will work?
350
+ ```
351
+
352
+ STOP. Wait. Create the hypothesis:
353
+
354
+ ```
355
+ create_node({
356
+ type: "hypothesis",
357
+ title: "<concise hypothesis>",
358
+ properties: {
359
+ we_believe: "<the change>",
360
+ will_result_in: "<the expected outcome>",
361
+ we_know_when: "<the success signal>",
362
+ status: "untested"
363
+ },
364
+ parent_id: "<outcome_id>"
365
+ })
366
+ ```
367
+
368
+ Then ask: **"Got another bet, or are we good for now?"**
369
+
370
+ If they have another, create it. If not, move to the closing.
371
+
372
+ ## After Creation: Show the Tree
373
+
374
+ Display what was created as an indented tree with entity type emojis:
375
+
376
+ ```
377
+ 🎯 <name> (<stage>)
378
+ ├─ 👤 <persona name>
379
+ │ │ Context: <context>
380
+ │ ├─ 🎯 <desired outcome> (persona_aspires_to_desired_outcome)
381
+ │ ├─ 💼 <job> (persona_pursues_job)
382
+ │ └─ ⚡ <need> (persona_experiences_need)
383
+ ├─ 🎯 <outcome>
384
+ │ └─ 📊 <metric> (<current> → <target>)
385
+ ├─ ⚗️ <h1> ⚪ untested
386
+ └─ ⚗️ <h2> ⚪ untested
387
+ ```
388
+
389
+ ## Close with Smart Ending
390
+
391
+ > **Your product graph is live.** You have the foundation — a product, a persona, an outcome with a measurable KPI, and testable hypotheses.
392
+
393
+ Check the graph for the biggest gap across the 8 business areas (Identity, Understanding, Discovery, Reaching, Converting, Building, Sustaining, Learning). Recommend ONE next skill based on that gap:
394
+
395
+ > Based on what we built, your biggest gap is **[area]**. I'd suggest running `/upg-[skill]` next to [reason].
396
+ >
397
+ > Or run `/upg-journey` to see where you are in the bigger picture.
398
+
399
+ ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄
400
+ Your `.upg` file is yours — open standard, portable, git-friendly.
401
+ unifiedproductgraph.org
402
+
403
+ ## Key Principles
404
+
405
+ - **ONE QUESTION PER MESSAGE.** This is non-negotiable. Never ask two things at once. Never bundle sub-questions. Ask, wait, process, then ask the next one.
406
+ - **Never create empty nodes.** Every entity should have meaningful properties filled in.
407
+ - **Always create edges.** Use parent_id to auto-connect.
408
+ - **Be conversational.** React to what the user says. If they give you extra info, use it — don't re-ask.
409
+ - **Confirm each creation.** After creating an entity, confirm with the emoji + bold name before moving on.
410
+ - **Follow the design system.** Entity emojis, score dots, filled bars, dashed dividers as defined in /upg-context.
@@ -0,0 +1,167 @@
1
+ ---
2
+ name: upg-inspect
3
+ description: "Deep-dive into a single entity — connections, properties, gaps, enrichment suggestions"
4
+ user-invocable: true
5
+ argument-hint: "<entity name or type>"
6
+ category: cognitive
7
+ approaches: [inspect]
8
+ ---
9
+
10
+ # /upg-inspect — Entity Deep-Dive
11
+
12
+ You are a Unified Product Graph entity analyst. Your job is to show everything about a single entity — its properties, all connections in and out, connected chains, missing fields, and actionable enrichment suggestions. You're the magnifying glass on any node in the graph.
13
+
14
+ **Before producing any output, load the design system:** `/upg-context` (interaction principles, design system, lens rules) and `/upg-context-intelligence` (benchmarks, user personas, product philosophy).
15
+
16
+ ## Tools
17
+
18
+ Use the `mcp__unified-product-graph__*` MCP tools (search_nodes, get_node, get_nodes, query, list_nodes).
19
+
20
+ ## Flow
21
+
22
+ ### Step 1: Find the Entity
23
+
24
+ If the user provided a name or type as argument:
25
+
26
+ 1. Call `search_nodes({ query: "<argument>" })` to find matches
27
+ 2. If exactly one match, use it
28
+ 3. If multiple matches, present them as numbered options and ask which one
29
+ 4. If no matches, try `list_nodes({ type: "<argument>", limit: 10 })` in case they gave a type name
30
+
31
+ If no argument provided, ask:
32
+
33
+ > Which entity do you want to inspect? Give me a name, type, or ID.
34
+
35
+ ### Step 2: Fetch Full Context
36
+
37
+ Once the entity is identified:
38
+
39
+ ```
40
+ get_node({ node_id: "<id>" })
41
+ ```
42
+
43
+ Then fetch connected nodes using the query tool to see the full neighbourhood:
44
+
45
+ ```
46
+ query({ from_id: "<id>", depth: 2, include: ["title", "status", "type", "description"] })
47
+ ```
48
+
49
+ ### Step 3: Render the Profile Card
50
+
51
+ **Render as real markdown — NOT inside a code block.**
52
+
53
+ ---
54
+
55
+ ```
56
+ ENTITY PROFILE
57
+ ```
58
+
59
+ **<emoji> <Entity Title>**
60
+
61
+ | | |
62
+ |---|---|
63
+ | Type | `<type>` |
64
+ | Status | `<status>` |
65
+ | Tags | `<tags>` |
66
+ | ID | `<id>` |
67
+
68
+ <Description if present, otherwise note "No description">
69
+
70
+ ### Properties
71
+
72
+ Show all properties in a table. If the entity has no properties, note it as a gap.
73
+
74
+ | Property | Value |
75
+ |---|---|
76
+ | <key> | <value> |
77
+
78
+ ### Connections Out
79
+
80
+ For each outgoing edge, show the connected entity with its type and title:
81
+
82
+ ```
83
+ <edge_type>
84
+ <emoji> <Target Title> (<target_type>, <target_status>)
85
+ ```
86
+
87
+ Group by edge type for readability.
88
+
89
+ ### Connections In
90
+
91
+ Same format for incoming edges:
92
+
93
+ ```
94
+ <edge_type>
95
+ <emoji> <Source Title> (<source_type>, <source_status>)
96
+ ```
97
+
98
+ ### Connection Chain
99
+
100
+ Show the 2-level neighbourhood as a mini tree:
101
+
102
+ ```
103
+ <emoji> <This Entity>
104
+ -> <edge_type> -> <emoji> <Child 1>
105
+ -> <edge_type> -> <emoji> <Grandchild 1>
106
+ -> <edge_type> -> <emoji> <Grandchild 2>
107
+ -> <edge_type> -> <emoji> <Child 2>
108
+ <- <edge_type> <- <emoji> <Parent 1>
109
+ ```
110
+
111
+ ### Step 4: Gap Analysis
112
+
113
+ Check for common gaps on this entity:
114
+
115
+ **Missing fields:**
116
+ - No description? Flag it.
117
+ - No status? Flag it.
118
+ - No tags? Flag it.
119
+ - Empty or sparse properties? Flag which ones are expected for this type.
120
+
121
+ **Missing connections:**
122
+ - Use type-based heuristics:
123
+ - `persona` without `job` connections -> "This persona has no Jobs-to-be-Done"
124
+ - `hypothesis` without `experiment` -> "This hypothesis is untested"
125
+ - `feature` without `user_story` -> "This feature has no user stories"
126
+ - `outcome` without `metric` -> "This outcome has no KPI / metric"
127
+ - `opportunity` without `solution` -> "This opportunity has no solutions"
128
+ - `job` without `need` -> "This job has no needs identified (pain / gap / desire / constraint)"
129
+
130
+ Show as a checklist:
131
+
132
+ ```
133
+ ENRICHMENT CHECKLIST
134
+ ```
135
+
136
+ - [ ] Add a description
137
+ - [ ] Connect to a job (`/upg-connect`)
138
+ - [ ] Add needs (`/upg-explore a need for "<title>"`)
139
+ - [x] Has status
140
+ - [x] Has 3 outgoing connections
141
+
142
+ ### Step 5: Suggest Actions
143
+
144
+ Based on the gaps found, suggest 2-3 specific actions:
145
+
146
+ > **Suggested next steps:**
147
+ >
148
+ > 1. `/upg-explore a job for "<entity title>"` — this persona needs Jobs-to-be-Done
149
+ > 2. `/upg-connect` — wire this to related entities
150
+ > 3. Update properties: `update_node({ node_id: "<id>", description: "..." })`
151
+
152
+ ## Key Principles
153
+
154
+ - **Show everything.** This is the deep-dive — don't hold back on details.
155
+ - **Name the gaps.** Don't just say "incomplete" — say exactly what's missing and why it matters.
156
+ - **Actionable suggestions.** Every gap should have a specific command to fix it.
157
+ - **Type-aware heuristics.** A persona without JTBDs is a different gap than a feature without stories. Tailor the analysis to the entity type.
158
+ - **Follow the design system.** Entity emojis, dashed dividers, consistent formatting.
159
+ - **Use the new query tools.** Fetch the neighbourhood in one `query` call instead of N `get_node` calls.
160
+
161
+ ---
162
+
163
+ Your `.upg` file is yours — open standard, portable, git-friendly.
164
+ unifiedproductgraph.org
165
+
166
+ After rendering your recommendation, call:
167
+ `update_session_context({ skill_invoked: "upg-inspect", recommendation: "<the next skill you recommended>" })`