@unified-product-graph/core 0.8.16 → 0.9.1

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/index.js CHANGED
@@ -91,7 +91,7 @@ var UPG_DOMAINS = [
91
91
  {
92
92
  id: "product_spec",
93
93
  label: "Product Specification",
94
- description: "What you are building and shipping. Feature areas group related capabilities. Features, epics, and user stories break work down. Acceptance criteria define done. Tasks and bugs track execution. Releases and changelogs mark what shipped. Roadmaps and roadmap items plan what comes next. Themes group strategic bets. Translates Strategy into Engineering and tracks delivery through Program Management.",
94
+ description: "What you are building and shipping. Feature areas group related capabilities. Features, epics, and user stories break work down. Acceptance criteria define done. Tasks and bugs track execution. Releases and changelogs mark what shipped. Roadmaps and roadmap items plan what comes next. Roadmap themes group roadmap work around the customer problem it solves, one level down from the strategic themes in Strategy. Translates Strategy into Engineering and tracks delivery through Program Management.",
95
95
  types: [
96
96
  "feature",
97
97
  "feature_area",
@@ -103,7 +103,7 @@ var UPG_DOMAINS = [
103
103
  "bug",
104
104
  "roadmap",
105
105
  "roadmap_item",
106
- "theme",
106
+ "roadmap_theme",
107
107
  "changelog"
108
108
  ]
109
109
  },
@@ -536,8 +536,8 @@ var UPG_ENTITY_META = [
536
536
  { name: "need", type_id: "ent_313", maturity: "stable", since: "0.1.0" },
537
537
  { name: "switching_cost", type_id: "ent_022", maturity: "stable", since: "0.1.0" },
538
538
  // ── Discovery ──
539
- { name: "opportunity", type_id: "ent_023", maturity: "stable", since: "0.1.0" },
540
- { name: "solution", type_id: "ent_024", maturity: "stable", since: "0.1.0" },
539
+ { name: "opportunity", type_id: "ent_023", maturity: "stable", since: "0.1.0", default_frameworks: ["opportunity-sizing", "rice-scoring"] },
540
+ { name: "solution", type_id: "ent_024", maturity: "stable", since: "0.1.0", default_frameworks: ["rice-scoring"] },
541
541
  { name: "feasibility_study", type_id: "ent_025", maturity: "stable", since: "0.1.0" },
542
542
  { name: "design_sprint", type_id: "ent_026", maturity: "stable", since: "0.1.0" },
543
543
  // ── Validation ──
@@ -638,7 +638,8 @@ var UPG_ENTITY_META = [
638
638
  { name: "bug", type_id: "ent_077", maturity: "stable", since: "0.1.0" },
639
639
  { name: "roadmap", type_id: "ent_078", maturity: "stable", since: "0.1.0" },
640
640
  { name: "roadmap_item", type_id: "ent_079", maturity: "stable", since: "0.1.0" },
641
- { name: "theme", type_id: "ent_080", maturity: "stable", since: "0.1.0" },
641
+ { name: "theme", type_id: "ent_080", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.9.0", replacement: "roadmap_theme" },
642
+ { name: "roadmap_theme", type_id: "ent_351", maturity: "stable", since: "0.1.0" },
642
643
  { name: "changelog", type_id: "ent_081", maturity: "stable", since: "0.1.0" },
643
644
  // ── Engineering ──
644
645
  { name: "bounded_context", type_id: "ent_082", maturity: "stable", since: "0.1.0" },
@@ -1154,6 +1155,12 @@ var UPG_EDGE_CATALOG = {
1154
1155
  strategic_pillar_delivers_value_stream: { forward_verb: "delivers", reverse_verb: "delivered_by", classification: "hierarchy", source_type: "strategic_pillar", target_type: "value_stream" },
1155
1156
  strategic_pillar_decided_via_decision: { forward_verb: "decided_via", reverse_verb: "decided_for", classification: "hierarchy", source_type: "strategic_pillar", target_type: "decision" },
1156
1157
  strategic_theme_pursues_initiative: { forward_verb: "pursues", reverse_verb: "pursued_under", classification: "hierarchy", source_type: "strategic_theme", target_type: "initiative" },
1158
+ // v0.9.0 (UPG-660): the soft bridge from the annual strategy focus area to the
1159
+ // roadmap grouping that realises it. Semantic, NOT hierarchy: strategic_theme and
1160
+ // roadmap_theme sit on different spines (strategy cascade vs roadmap cascade), so
1161
+ // this is a cross-reference, not containment. Pairs with the theme → roadmap_theme
1162
+ // rename that removed the bare-'theme' collision (N6/UPG-652 lineage).
1163
+ strategic_theme_realised_by_roadmap_theme: { forward_verb: "realised_by", reverse_verb: "realises", classification: "semantic", source_type: "strategic_theme", target_type: "roadmap_theme" },
1157
1164
  // v0.5.4 (UPG-511): three edges that lift strategic_theme from structural
1158
1165
  // isolation to a conceptually central strategy node.
1159
1166
  //
@@ -1211,7 +1218,7 @@ var UPG_EDGE_CATALOG = {
1211
1218
  product_builds_feature: { forward_verb: "builds", reverse_verb: "built_by", classification: "hierarchy", source_type: "product", target_type: "feature" },
1212
1219
  product_ships_via_release: { forward_verb: "ships_via", reverse_verb: "ships", classification: "hierarchy", source_type: "product", target_type: "release" },
1213
1220
  product_plans_via_roadmap: { forward_verb: "plans_via", reverse_verb: "plans_for", classification: "hierarchy", source_type: "product", target_type: "roadmap" },
1214
- product_categorises_by_theme: { forward_verb: "categorises_by", reverse_verb: "categorises", classification: "hierarchy", source_type: "product", target_type: "theme" },
1221
+ product_categorises_by_roadmap_theme: { forward_verb: "categorises_by", reverse_verb: "categorises", classification: "hierarchy", source_type: "product", target_type: "roadmap_theme" },
1215
1222
  feature_area_contains_feature: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "feature_area", target_type: "feature" },
1216
1223
  feature_area_contains_feature_area: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "feature_area", target_type: "feature_area" },
1217
1224
  outcome_delivered_by_feature: { forward_verb: "delivered_by", reverse_verb: "delivers", classification: "cross-domain", source_type: "outcome", target_type: "feature" },
@@ -1235,12 +1242,12 @@ var UPG_EDGE_CATALOG = {
1235
1242
  release_contains_bug: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "release", target_type: "bug" },
1236
1243
  release_documented_in_changelog: { forward_verb: "documented_in", reverse_verb: "documents", classification: "hierarchy", source_type: "release", target_type: "changelog" },
1237
1244
  roadmap_contains_roadmap_item: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "roadmap", target_type: "roadmap_item" },
1238
- roadmap_categorised_by_theme: { forward_verb: "categorised_by", reverse_verb: "categorises", classification: "hierarchy", source_type: "roadmap", target_type: "theme" },
1245
+ roadmap_categorised_by_roadmap_theme: { forward_verb: "categorised_by", reverse_verb: "categorises", classification: "hierarchy", source_type: "roadmap", target_type: "roadmap_theme" },
1239
1246
  roadmap_schedules_release: { forward_verb: "schedules", reverse_verb: "scheduled_in", classification: "hierarchy", source_type: "roadmap", target_type: "release" },
1240
- theme_groups_feature: { forward_verb: "groups", reverse_verb: "grouped_in", classification: "hierarchy", source_type: "theme", target_type: "feature" },
1241
- // feature_area is not contained by theme; themes span multiple
1247
+ roadmap_theme_groups_feature: { forward_verb: "groups", reverse_verb: "grouped_in", classification: "hierarchy", source_type: "roadmap_theme", target_type: "feature" },
1248
+ // feature_area is not contained by roadmap_theme; roadmap themes span multiple
1242
1249
  // areas cross-cuttingly. Containment path: product → feature_area.
1243
- theme_spans_feature_area: { forward_verb: "spans", reverse_verb: "spanned_by", classification: "semantic", source_type: "theme", target_type: "feature_area" },
1250
+ roadmap_theme_spans_feature_area: { forward_verb: "spans", reverse_verb: "spanned_by", classification: "semantic", source_type: "roadmap_theme", target_type: "feature_area" },
1244
1251
  // The legacy `story_task` collapsed into `task` (v0.4.0), so the implements
1245
1252
  // relationship is the canonical `task_implements_user_story` above; there is
1246
1253
  // no separate story_task edge. (v0.2.7 introduced the Statement/Implementation
@@ -2752,7 +2759,8 @@ var UPG_CROSS_EDGE_TYPES = [
2752
2759
  "depends_on_product",
2753
2760
  "cannibalises",
2754
2761
  "succeeds",
2755
- "hosts"
2762
+ "hosts",
2763
+ "contributes_to"
2756
2764
  ];
2757
2765
 
2758
2766
  // src/registry/entity-type-resolution.ts
@@ -2850,7 +2858,7 @@ var UPG_VALID_CHILDREN = {
2850
2858
  "feature_area",
2851
2859
  "release",
2852
2860
  "roadmap",
2853
- "theme",
2861
+ "roadmap_theme",
2854
2862
  // Engineering
2855
2863
  "bounded_context",
2856
2864
  "code_repository",
@@ -3246,8 +3254,8 @@ var UPG_VALID_CHILDREN = {
3246
3254
  a11y_standard: ["a11y_guideline", "a11y_audit", "a11y_annotation"],
3247
3255
  a11y_audit: ["a11y_issue"],
3248
3256
  // ── Product Specification expansion ─────────────────────────────────────────
3249
- roadmap: ["roadmap_item", "theme", "release"],
3250
- theme: ["feature"],
3257
+ roadmap: ["roadmap_item", "roadmap_theme", "release"],
3258
+ roadmap_theme: ["feature"],
3251
3259
  // ── Unified Context Layer hierarchy ─────────────────────────────────────────
3252
3260
  design_system: [
3253
3261
  "design_component",
@@ -5860,7 +5868,7 @@ var UPG_LIFECYCLE_FREE_TYPES = /* @__PURE__ */ new Set([
5860
5868
  // v0.7.0/UPG-571. ─
5861
5869
  "acceptance_criterion",
5862
5870
  "changelog",
5863
- "theme",
5871
+ "roadmap_theme",
5864
5872
  "user_story",
5865
5873
  // ── Strategy: metric is a measurement definition; metric_quality_assessment
5866
5874
  // is a point-in-time snapshot; value_stream is a mapped flow;
@@ -6540,6 +6548,21 @@ function getEnumValueMeta(scaleName, value) {
6540
6548
 
6541
6549
  // src/grammar/migrations.ts
6542
6550
  var UPG_MIGRATIONS = {
6551
+ "0.9.0": [
6552
+ // (since v0.9.0, UPG-660) theme → roadmap_theme. `theme` was the only bare,
6553
+ // unqualified theme among four domain-prefixed siblings (strategic_theme,
6554
+ // content_theme, feedback_theme); it claimed the unqualified word and read as
6555
+ // interchangeable with strategic_theme (the N6/UPG-652 confusion). Renamed to
6556
+ // roadmap_theme so all four read consistently and the customer-problem roadmap
6557
+ // grouping is explicit. Lifecycle-free, identical property surface (theme_scope
6558
+ // / priority); no property migration required. Paired edge renames live in
6559
+ // UPG_EDGE_MIGRATIONS['0.9.0'].
6560
+ {
6561
+ from: "theme",
6562
+ to: "roadmap_theme",
6563
+ reason: 'theme renamed to roadmap_theme (UPG-660). The bare "theme" was the only domain-unprefixed theme among strategic_theme / content_theme / feedback_theme; it grabbed the unqualified word and read as interchangeable with strategic_theme. roadmap_theme makes the customer-problem roadmap grouping explicit and consistent across the four. Same property surface (theme_scope / priority); no property migration needed.'
6564
+ }
6565
+ ],
6543
6566
  "0.7.0": [
6544
6567
  // (since v0.7.0, UPG-571) story_statement → user_story. The v0.2.7 split
6545
6568
  // correctly separated the templated promise from the engineering work
@@ -7582,6 +7605,17 @@ function getSplitMigrations(fromVersion, toVersion) {
7582
7605
  return result;
7583
7606
  }
7584
7607
  var UPG_EDGE_MIGRATIONS = {
7608
+ "0.9.0": [
7609
+ // (since v0.9.0, UPG-660) theme → roadmap_theme. The four canonical edges that
7610
+ // touch the roadmap theme are renamed to the roadmap_theme form. Endpoint guards
7611
+ // reference the POST-migration (roadmap_theme) types; edge migration runs after
7612
+ // node migration, so by the time these rules apply the node has already been
7613
+ // renamed theme → roadmap_theme (UPG_MIGRATIONS['0.9.0']).
7614
+ { kind: "rename", from: "product_categorises_by_theme", to: "product_categorises_by_roadmap_theme", requires_source_type: "product", requires_target_type: "roadmap_theme", reason: "theme \u2192 roadmap_theme (UPG-660). Product categorises by the roadmap theme; edge key updated to the renamed target type." },
7615
+ { kind: "rename", from: "roadmap_categorised_by_theme", to: "roadmap_categorised_by_roadmap_theme", requires_source_type: "roadmap", requires_target_type: "roadmap_theme", reason: "theme \u2192 roadmap_theme (UPG-660). Roadmap is categorised by the roadmap theme; edge key updated to the renamed target type." },
7616
+ { kind: "rename", from: "theme_groups_feature", to: "roadmap_theme_groups_feature", requires_source_type: "roadmap_theme", requires_target_type: "feature", reason: "theme \u2192 roadmap_theme (UPG-660). The roadmap theme groups features; edge key updated to the renamed source type." },
7617
+ { kind: "rename", from: "theme_spans_feature_area", to: "roadmap_theme_spans_feature_area", requires_source_type: "roadmap_theme", requires_target_type: "feature_area", reason: "theme \u2192 roadmap_theme (UPG-660). The roadmap theme spans feature areas; edge key updated to the renamed source type." }
7618
+ ],
7585
7619
  "0.7.0": [
7586
7620
  // (since v0.7.0, UPG-571) story_statement → user_story re-canon. The four
7587
7621
  // canonical edges that touch the statement are renamed to the user_story
@@ -10478,7 +10512,7 @@ var UPG_PROPERTY_SCHEMA = {
10478
10512
  reach: {
10479
10513
  type: "assessment",
10480
10514
  scale_id: "reach_5",
10481
- description: "How many users experience this problem",
10515
+ description: "How many users experience this problem. @deprecated 0.9.0:a framework-scoped scoring input, not an intrinsic property. Apply the `opportunity-sizing` framework; the value lives on the framework_exercise includes-edge. Removed in 0.9.1.",
10482
10516
  properties: {
10483
10517
  value: { type: "number", description: "The numeric value, used for computation." },
10484
10518
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -10490,7 +10524,7 @@ var UPG_PROPERTY_SCHEMA = {
10490
10524
  frequency: {
10491
10525
  type: "assessment",
10492
10526
  scale_id: "frequency_5",
10493
- description: "How often users experience this problem",
10527
+ description: "How often users experience this problem. @deprecated 0.9.0:framework-scoped (opportunity-sizing). Removed in 0.9.1.",
10494
10528
  properties: {
10495
10529
  value: { type: "number", description: "The numeric value, used for computation." },
10496
10530
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -10502,7 +10536,7 @@ var UPG_PROPERTY_SCHEMA = {
10502
10536
  pain: {
10503
10537
  type: "assessment",
10504
10538
  scale_id: "pain_5",
10505
- description: "How painful it is when unaddressed",
10539
+ description: "How painful it is when unaddressed. @deprecated 0.9.0:framework-scoped (opportunity-sizing). Removed in 0.9.1.",
10506
10540
  properties: {
10507
10541
  value: { type: "number", description: "The numeric value, used for computation." },
10508
10542
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -10511,7 +10545,7 @@ var UPG_PROPERTY_SCHEMA = {
10511
10545
  },
10512
10546
  required: ["value", "label"]
10513
10547
  },
10514
- opportunity_score: { type: "number", description: "Computed: normalized_reach x normalized_frequency x normalized_pain (0-1)" }
10548
+ opportunity_score: { type: "number", description: "Computed: normalized_reach x normalized_frequency x normalized_pain (0-1). @deprecated 0.9.0:computed by the `opportunity-sizing` framework on its application edge, not stored on the entity. Removed in 0.9.1." }
10515
10549
  },
10516
10550
  // OrganizationProperties: Organization entity.
10517
10551
  organization: {
@@ -10925,6 +10959,11 @@ var UPG_PROPERTY_SCHEMA = {
10925
10959
  start_date: { type: "string", description: "ISO date work begins. More precise than `quarter` for continuous planning." },
10926
10960
  target_date: { type: "string", description: "ISO date completion is expected. For shipped items, the actual completion date." }
10927
10961
  },
10962
+ // RoadmapThemeProperties: Thematic grouping of roadmap work, around the customer problem it solves.
10963
+ roadmap_theme: {
10964
+ theme_scope: { type: "string", description: "Scope description" },
10965
+ priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Priority" }
10966
+ },
10928
10967
  // RoleProperties: Role entity.
10929
10968
  role: {
10930
10969
  responsibilities: { type: "string[]", description: "Key responsibilities of the role" },
@@ -11110,7 +11149,7 @@ var UPG_PROPERTY_SCHEMA = {
11110
11149
  reach: {
11111
11150
  type: "assessment",
11112
11151
  scale_id: "reach_5",
11113
- description: "How many users this solution reaches (1 = few, 5 = most)",
11152
+ description: "How many users this solution reaches (1 = few, 5 = most). @deprecated 0.9.0:a framework-scoped scoring input, not an intrinsic property. Apply the `rice-scoring` framework; the value lives on the framework_exercise includes-edge. Removed in 0.9.1.",
11114
11153
  properties: {
11115
11154
  value: { type: "number", description: "The numeric value, used for computation." },
11116
11155
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -11122,7 +11161,7 @@ var UPG_PROPERTY_SCHEMA = {
11122
11161
  impact: {
11123
11162
  type: "assessment",
11124
11163
  scale_id: "impact_5",
11125
- description: "Expected impact on the target outcome (1 = minimal, 5 = transformative)",
11164
+ description: "Expected impact on the target outcome (1 = minimal, 5 = transformative). @deprecated 0.9.0:framework-scoped (rice-scoring). Removed in 0.9.1.",
11126
11165
  properties: {
11127
11166
  value: { type: "number", description: "The numeric value, used for computation." },
11128
11167
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -11134,7 +11173,7 @@ var UPG_PROPERTY_SCHEMA = {
11134
11173
  confidence: {
11135
11174
  type: "assessment",
11136
11175
  scale_id: "confidence_5",
11137
- description: "How confident the team is in this solution (1 = speculative, 5 = proven)",
11176
+ description: "How confident the team is in this solution (1 = speculative, 5 = proven). @deprecated 0.9.0:framework-scoped (rice-scoring). Removed in 0.9.1.",
11138
11177
  properties: {
11139
11178
  value: { type: "number", description: "The numeric value, used for computation." },
11140
11179
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -11146,7 +11185,7 @@ var UPG_PROPERTY_SCHEMA = {
11146
11185
  effort: {
11147
11186
  type: "assessment",
11148
11187
  scale_id: "effort_5",
11149
- description: "Level of effort required to implement (1 = trivial, 5 = very large)",
11188
+ description: "Level of effort required to implement (1 = trivial, 5 = very large). @deprecated 0.9.0:effort is a framework-scoped scoring input (it varies by assessor and method), not an intrinsic property. Removed in 0.9.1.",
11150
11189
  properties: {
11151
11190
  value: { type: "number", description: "The numeric value, used for computation." },
11152
11191
  label: { type: "string", description: "The qualitative label (what the assessor meant)." },
@@ -11155,7 +11194,7 @@ var UPG_PROPERTY_SCHEMA = {
11155
11194
  },
11156
11195
  required: ["value", "label"]
11157
11196
  },
11158
- rice_score: { type: "number", description: "Computed: (reach \xD7 impact \xD7 confidence) / effort" }
11197
+ rice_score: { type: "number", description: "Computed: (reach \xD7 impact \xD7 confidence) / effort. @deprecated 0.9.0:computed by the `rice-scoring` framework on its application edge, not stored on the entity. Removed in 0.9.1." }
11159
11198
  },
11160
11199
  // StakeholderProperties: Stakeholder entity.
11161
11200
  stakeholder: {
@@ -11402,11 +11441,6 @@ var UPG_PROPERTY_SCHEMA = {
11402
11441
  skipped_count: { type: "number", description: "Number of tests that were skipped in the last run" },
11403
11442
  flaky_count: { type: "number", description: "Number of tests that passed only on retry (flaky) in the last run" }
11404
11443
  },
11405
- // ThemeProperties: Thematic grouping of work.
11406
- theme: {
11407
- theme_scope: { type: "string", description: "Scope description" },
11408
- priority: { type: "string", enum: ["urgent", "high", "medium", "low", "none"], description: "Priority" }
11409
- },
11410
11444
  // ThreatProperties: Threat.
11411
11445
  threat: {
11412
11446
  category: { type: "string", description: 'Attack or threat scenario. @example "injection", "misconfiguration", "social engineering", "supply chain"' },
@@ -11637,6 +11671,188 @@ function getPropertySchema(entityType) {
11637
11671
 
11638
11672
  // src/frameworks/canonical.ts
11639
11673
  var UPG_FRAMEWORKS = [
11674
+ {
11675
+ "id": "opportunity-sizing",
11676
+ "approach_ids": [
11677
+ "prioritise"
11678
+ ],
11679
+ "name": "Opportunity Sizing",
11680
+ "version": "1.0.0",
11681
+ "description": "Size opportunities by Reach, Frequency, and Pain to rank which problems are most worth solving before committing to solutions.",
11682
+ "category": "prioritization",
11683
+ "origin": {
11684
+ "type": "practitioner",
11685
+ "attribution": "Continuous discovery practice",
11686
+ "description": "A lightweight discovery-prioritisation method: weigh how many users hit a problem, how often, and how much it hurts, to rank opportunities before investing in solutions.",
11687
+ "url": "https://www.producttalk.org/2016/08/opportunity-solution-tree/",
11688
+ "year": 2016,
11689
+ "license": "open_attribution"
11690
+ },
11691
+ "tags": [
11692
+ "prioritization",
11693
+ "discovery",
11694
+ "table"
11695
+ ],
11696
+ "slots": [
11697
+ {
11698
+ "label": "Opportunities to size",
11699
+ "entityTypeId": "opportunity",
11700
+ "description": "Opportunities scored on Reach, Frequency, and Pain."
11701
+ }
11702
+ ],
11703
+ "data": {
11704
+ "entity_types": [
11705
+ {
11706
+ "type": "opportunity",
11707
+ "role": "scored_item"
11708
+ }
11709
+ ],
11710
+ "required_properties": {
11711
+ "opportunity": [
11712
+ {
11713
+ "property": "reach",
11714
+ "type": "assessment",
11715
+ "scale_id": "reach_5",
11716
+ "required": true,
11717
+ "scope": "framework",
11718
+ "label": "Reach",
11719
+ "description": "How many users experience this problem?"
11720
+ },
11721
+ {
11722
+ "property": "frequency",
11723
+ "type": "assessment",
11724
+ "scale_id": "frequency_5",
11725
+ "required": true,
11726
+ "scope": "framework",
11727
+ "label": "Frequency",
11728
+ "description": "How often do they run into it?"
11729
+ },
11730
+ {
11731
+ "property": "pain",
11732
+ "type": "assessment",
11733
+ "scale_id": "pain_5",
11734
+ "required": true,
11735
+ "scope": "framework",
11736
+ "label": "Pain",
11737
+ "description": "How painful is it when left unaddressed?"
11738
+ }
11739
+ ]
11740
+ },
11741
+ "computed_properties": [
11742
+ {
11743
+ "property": "opportunity_score",
11744
+ "expression": "reach * frequency * pain",
11745
+ "entity_type": "opportunity",
11746
+ "label": "Opportunity Score",
11747
+ "format": "number"
11748
+ }
11749
+ ],
11750
+ "scoring_method": {
11751
+ "applies_to": [
11752
+ "opportunity"
11753
+ ],
11754
+ "inputs": [
11755
+ {
11756
+ "property": "reach",
11757
+ "type": "assessment",
11758
+ "scale_id": "reach_5",
11759
+ "required": true,
11760
+ "scope": "framework",
11761
+ "label": "Reach",
11762
+ "description": "How many users experience this problem?"
11763
+ },
11764
+ {
11765
+ "property": "frequency",
11766
+ "type": "assessment",
11767
+ "scale_id": "frequency_5",
11768
+ "required": true,
11769
+ "scope": "framework",
11770
+ "label": "Frequency",
11771
+ "description": "How often do they run into it?"
11772
+ },
11773
+ {
11774
+ "property": "pain",
11775
+ "type": "assessment",
11776
+ "scale_id": "pain_5",
11777
+ "required": true,
11778
+ "scope": "framework",
11779
+ "label": "Pain",
11780
+ "description": "How painful is it when left unaddressed?"
11781
+ }
11782
+ ],
11783
+ "computed": [
11784
+ {
11785
+ "property": "opportunity_score",
11786
+ "expression": "reach * frequency * pain",
11787
+ "label": "Opportunity Score",
11788
+ "format": "number"
11789
+ }
11790
+ ]
11791
+ }
11792
+ },
11793
+ "structure": {
11794
+ "pattern": "table"
11795
+ },
11796
+ "presentation": {
11797
+ "layout": {
11798
+ "type": "table",
11799
+ "columns": [
11800
+ {
11801
+ "property": "title",
11802
+ "label": "Opportunities to size",
11803
+ "sortable": true
11804
+ },
11805
+ {
11806
+ "property": "reach",
11807
+ "label": "Reach",
11808
+ "sortable": true,
11809
+ "format": "number"
11810
+ },
11811
+ {
11812
+ "property": "frequency",
11813
+ "label": "Frequency",
11814
+ "sortable": true,
11815
+ "format": "number"
11816
+ },
11817
+ {
11818
+ "property": "pain",
11819
+ "label": "Pain",
11820
+ "sortable": true,
11821
+ "format": "number"
11822
+ },
11823
+ {
11824
+ "property": "opportunity_score",
11825
+ "label": "Opportunity Score",
11826
+ "sortable": true,
11827
+ "format": "score_pill"
11828
+ }
11829
+ ]
11830
+ },
11831
+ "sort_by": {
11832
+ "property": "opportunity_score",
11833
+ "direction": "desc"
11834
+ },
11835
+ "colour_by": "score",
11836
+ "card_fields": [
11837
+ "title",
11838
+ "description",
11839
+ "status"
11840
+ ]
11841
+ },
11842
+ "education": {
11843
+ "purpose": "Rank opportunities by how widely, how often, and how painfully a problem is felt, so discovery effort flows to the problems most worth solving.",
11844
+ "core_question": "Of the problems we could pursue, which affect the most users, most often, with the most pain?",
11845
+ "when_to_use": [
11846
+ "You have more opportunities than you can pursue",
11847
+ "You need to compare problems before committing to solutions",
11848
+ "You want a defensible, transparent way to choose what to explore"
11849
+ ],
11850
+ "when_not_to_use": [
11851
+ "A single opportunity is already validated and obvious",
11852
+ "You have no signal yet on reach, frequency, or pain"
11853
+ ]
11854
+ }
11855
+ },
11640
11856
  {
11641
11857
  "id": "opportunity-solution-tree",
11642
11858
  "approach_ids": [
@@ -12893,7 +13109,7 @@ var UPG_FRAMEWORKS = [
12893
13109
  ],
12894
13110
  "name": "RICE Scoring",
12895
13111
  "version": "1.0.0",
12896
- "description": "Score features, opportunities, and needs by Reach, Impact, Confidence, and Effort to produce a ranked priority list.",
13112
+ "description": "Score features, solutions, opportunities, and needs by Reach, Impact, Confidence, and Effort to produce a ranked priority list.",
12897
13113
  "category": "prioritization",
12898
13114
  "origin": {
12899
13115
  "type": "practitioner",
@@ -12918,6 +13134,11 @@ var UPG_FRAMEWORKS = [
12918
13134
  "entityTypeId": "opportunity",
12919
13135
  "description": "Opportunities scored on the same RICE Scoring inputs as features."
12920
13136
  },
13137
+ {
13138
+ "label": "Solutions to score",
13139
+ "entityTypeId": "solution",
13140
+ "description": "Solutions scored on the same RICE Scoring inputs as features."
13141
+ },
12921
13142
  {
12922
13143
  "label": "Needs to score",
12923
13144
  "entityTypeId": "need",
@@ -12934,6 +13155,10 @@ var UPG_FRAMEWORKS = [
12934
13155
  "type": "opportunity",
12935
13156
  "role": "scored_item"
12936
13157
  },
13158
+ {
13159
+ "type": "solution",
13160
+ "role": "scored_item"
13161
+ },
12937
13162
  {
12938
13163
  "type": "need",
12939
13164
  "role": "scored_item"
@@ -13016,6 +13241,44 @@ var UPG_FRAMEWORKS = [
13016
13241
  "description": "How much work is required to build and ship this, on the effort scale?"
13017
13242
  }
13018
13243
  ],
13244
+ "solution": [
13245
+ {
13246
+ "property": "reach",
13247
+ "type": "assessment",
13248
+ "scale_id": "reach_5",
13249
+ "required": true,
13250
+ "scope": "framework",
13251
+ "label": "Reach",
13252
+ "description": "How many users will this impact per quarter?"
13253
+ },
13254
+ {
13255
+ "property": "impact",
13256
+ "type": "assessment",
13257
+ "scale_id": "impact_5",
13258
+ "required": true,
13259
+ "scope": "framework",
13260
+ "label": "Impact",
13261
+ "description": "How much will this impact each user, on the impact scale?"
13262
+ },
13263
+ {
13264
+ "property": "confidence",
13265
+ "type": "assessment",
13266
+ "scale_id": "confidence_5",
13267
+ "required": true,
13268
+ "scope": "framework",
13269
+ "label": "Confidence",
13270
+ "description": "How confident are you in the reach, impact, and effort estimates?"
13271
+ },
13272
+ {
13273
+ "property": "effort",
13274
+ "type": "assessment",
13275
+ "scale_id": "effort_5",
13276
+ "required": true,
13277
+ "scope": "framework",
13278
+ "label": "Effort",
13279
+ "description": "How much work is required to build and ship this, on the effort scale?"
13280
+ }
13281
+ ],
13019
13282
  "need": [
13020
13283
  {
13021
13284
  "property": "reach",
@@ -13070,6 +13333,13 @@ var UPG_FRAMEWORKS = [
13070
13333
  "label": "RICE Score",
13071
13334
  "format": "number"
13072
13335
  },
13336
+ {
13337
+ "property": "rice_score",
13338
+ "expression": "(reach * impact * confidence) / effort",
13339
+ "entity_type": "solution",
13340
+ "label": "RICE Score",
13341
+ "format": "number"
13342
+ },
13073
13343
  {
13074
13344
  "property": "rice_score",
13075
13345
  "expression": "(reach * impact * confidence) / effort",
@@ -13082,6 +13352,7 @@ var UPG_FRAMEWORKS = [
13082
13352
  "applies_to": [
13083
13353
  "feature",
13084
13354
  "opportunity",
13355
+ "solution",
13085
13356
  "need"
13086
13357
  ],
13087
13358
  "inputs": [
@@ -17764,7 +18035,8 @@ var STANDARD_LABELS = {
17764
18035
  product: { alt_labels: ["offering", "app", "service", "platform"] },
17765
18036
  vision: { alt_labels: ["product vision", "north star vision", "long-term vision"] },
17766
18037
  mission: { alt_labels: ["mission statement", "purpose"] },
17767
- strategic_theme: { alt_labels: ["theme", "strategic pillar", "focus area"] },
18038
+ strategic_theme: { alt_labels: ["focus area", "strategic focus area"] },
18039
+ // N6: not 'theme'/'strategic pillar' (own types)
17768
18040
  initiative: { alt_labels: ["strategic initiative", "program initiative", "workstream"] },
17769
18041
  capability: { alt_labels: ["business capability", "organizational capability"] },
17770
18042
  value_stream: { alt_labels: ["value chain", "stream"] },
@@ -17826,7 +18098,8 @@ var STANDARD_LABELS = {
17826
18098
  fix: { alt_labels: ["bugfix", "patch", "remediation"] },
17827
18099
  roadmap: { alt_labels: ["product roadmap", "release plan", "timeline"] },
17828
18100
  roadmap_item: { alt_labels: ["roadmap entry", "planned item"] },
17829
- theme: { alt_labels: ["product theme", "bucket", "category"] },
18101
+ roadmap_theme: { alt_labels: ["product theme", "roadmap theme"] },
18102
+ // UPG-660: renamed from bare 'theme' (N6 lineage)
17830
18103
  // Engineering layer
17831
18104
  bounded_context: { alt_labels: ["context", "domain boundary", "module boundary"] },
17832
18105
  service: { alt_labels: ["microservice", "backend service", "api service"] },
@@ -18025,7 +18298,8 @@ var STANDARD_LABELS = {
18025
18298
  feedback_vote: { alt_labels: ["upvote", "vote", "user vote"] },
18026
18299
  user_advisory_board: { alt_labels: ["cab", "customer advisory board", "advisory council"] },
18027
18300
  beta_program: { alt_labels: ["beta", "early access", "preview program"] },
18028
- feedback_theme: { alt_labels: ["feedback cluster", "theme", "feedback category"] },
18301
+ feedback_theme: { alt_labels: ["feedback cluster", "feedback category"] },
18302
+ // N6: not bare 'theme'
18029
18303
  // Pricing & Packaging layer
18030
18304
  pricing_strategy: { alt_labels: ["pricing model", "monetization strategy"] },
18031
18305
  package: { alt_labels: ["product package", "bundle", "sku"] },
@@ -18531,9 +18805,9 @@ var PRODUCT_DELIVERY_PLAYBOOK = {
18531
18805
  ),
18532
18806
  seqStep(
18533
18807
  6,
18534
- "Themes & Changelog",
18535
- ["theme", "changelog"],
18536
- "Group releases into strategic themes. Maintain a changelog the team and customers can read together."
18808
+ "Roadmap Themes & Changelog",
18809
+ ["roadmap_theme", "changelog"],
18810
+ "Group roadmap work into roadmap themes around the customer problem. Maintain a changelog the team and customers can read together."
18537
18811
  )
18538
18812
  ]
18539
18813
  };
@@ -19838,7 +20112,7 @@ var PRODUCT_SPEC_GUIDE = {
19838
20112
  // registered to product_spec but missing from the navigation order).
19839
20113
  // `changelog` lives here because it is a structural product-shipping
19840
20114
  // artefact; content domain references it only via cross-domain bridges.
19841
- creation_sequence: ["feature_area", "feature", "epic", "user_story", "acceptance_criterion", "task", "bug", "release", "roadmap", "roadmap_item", "theme", "changelog"],
20115
+ creation_sequence: ["feature_area", "feature", "epic", "user_story", "acceptance_criterion", "task", "bug", "release", "roadmap", "roadmap_item", "roadmap_theme", "changelog"],
19842
20116
  patterns: [
19843
20117
  {
19844
20118
  name: "Feature Decomposition",
@@ -24320,7 +24594,7 @@ var UPG_REGIONS = [
24320
24594
  role: "leaf"
24321
24595
  },
24322
24596
  {
24323
- type: "theme",
24597
+ type: "roadmap_theme",
24324
24598
  role: "container",
24325
24599
  notes: "semantic spanner, not containment"
24326
24600
  },
@@ -24356,10 +24630,10 @@ var UPG_REGIONS = [
24356
24630
  "user_story_verified_by_acceptance_criterion",
24357
24631
  "task_implements_user_story",
24358
24632
  "roadmap_contains_roadmap_item",
24359
- "roadmap_categorised_by_theme",
24633
+ "roadmap_categorised_by_roadmap_theme",
24360
24634
  "roadmap_schedules_release",
24361
24635
  "release_documented_in_changelog",
24362
- "theme_spans_feature_area",
24636
+ "roadmap_theme_spans_feature_area",
24363
24637
  "milestone_gates_release",
24364
24638
  "roadmap_item_references_feature",
24365
24639
  "feature_request_voted_on_by_feedback_vote"
@@ -25680,7 +25954,7 @@ function isCanonical(text) {
25680
25954
  }
25681
25955
 
25682
25956
  // src/index.ts
25683
- var UPG_VERSION = "0.8.16";
25957
+ var UPG_VERSION = "0.9.1";
25684
25958
  var UPG_FORMAT_VERSION = "0.4.0";
25685
25959
  var MARKDOWN_FORMAT_VERSION = "0.1";
25686
25960
  var UPG_TYPES = getTypes();