@unified-product-graph/core 0.9.14 → 0.9.16

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 CHANGED
@@ -7,6 +7,37 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.9.16] - 2026-06-11
11
+
12
+ **get_tree reaches the cloud, the show-tree skill calls it, and the three "area" taxonomies get a documented cross-walk.** 0.9.15 shipped `get_tree` local-only and left the show-tree skill on its interim hardcoded chains; this release finishes the loop and closes the deferred A4 introspection gap.
13
+
14
+ ### Added
15
+ - **`get_tree` on the cloud server** (cloud tools 94 to 95; local unchanged at 121). The assembler (`assembleTree` + the `GraphReader` interface) moved to the shared `@unified-product-graph/mcp-tooling` package, so the local file-backed server and the cloud Postgres-backed server assemble byte-identical trees from one source. The cloud handler builds an in-memory `GraphReader` from a one-shot product node+edge load. `get_tree` leaves the CLOUD_NA parity list.
16
+ - **`UPG_AREA_TAXONOMY`** (core): the documented cross-walk between the three overlapping "area" groupings that skills kept conflating into a stale coverage denominator: the 10 `get_graph_digest.coverage` keys, the 11 canonical regions, and the 8 "business areas". Keyed by coverage key; each row names the matching business area (null for `validation` and `operations`, which the 8-area grouping folds into discovery / omits) and the region ids its entities live in. Helpers `getCoverageKeysForRegion` / `getBusinessAreasForRegion`. Surfaced on `list_regions` (an `area_taxonomy` block plus per-region `coverage_keys` / `business_areas`) and `get_region` (per-region `coverage_keys` / `business_areas`), local and cloud. An SDK drift test pins the key sets against the runtime sources (`BUSINESS_AREAS`, `BUSINESS_AREA_META`).
17
+
18
+ ### Changed
19
+ - **`/upg-show-tree` calls `get_tree`** instead of building traverse chains and resolving edge names. The skill now renders the returned roots / children, surfaces `gaps`, and notes anchor fallback; it no longer carries the edge-name chains that drifted (the exact failure `get_tree` exists to prevent). Adds the `feature_areas` pattern. Skills ship in the mcp-server package, so this reaches users with the release.
20
+
21
+ No entity, domain, region, playbook, framework, or edge-count change, and no change to the local tool surface (entities 315, edges 980, local tools 121, regions 11).
22
+
23
+ ---
24
+
25
+ ## [0.9.15] - 2026-06-11
26
+
27
+ **get_tree: server-side tree assembly.** Tree views (OST, OKR, user, product, validation, strategy, feature areas) were assembled client-side by the show-tree skill out of multiple query calls and hardcoded edge chains that drifted with the spec. This release relocates assembly to the server, which owns the catalogue.
28
+
29
+ ### Added
30
+ - **`UPG_TREE_PATTERNS`** (core): 7 canonical tree patterns, each an anchor type + a TYPE-DRIVEN `child_map` (parent type to allowed child types), not a list of edge names. A pattern follows the live graph to a neighbour of the next expected type, whatever edge wired them, so a chain refinement in the edge catalogue cannot rot it (the failure mode that drifted the skill's hardcoded chains). Chains authored by resolving every pair against the live catalogue.
31
+ - **`get_tree`** (tools 120 to 121, local only): assembles a pattern from the active product graph and returns NESTED data plus structural `gaps` (a node whose pattern expects children the graph lacks: a bet with no initiative, an objective with no key result). Roots at the pattern anchor, falling back through `fallback_anchors` when the anchor has no nodes or reaches nothing (the "wrong root, empty tree" case), and reports the substitution (`anchor_resolved_from` / `anchor_used`). `max_nodes` summarises rather than silently truncating. Rendering (emoji, ASCII) stays in the client; the tool composes with `query` rather than replacing it.
32
+
33
+ ### Notes
34
+ - `query.traverse` is unchanged: its set-vs-positional semantics is a separate concern, and flipping it would break path-walk callers, so `get_tree` encapsulates the branching multi-pass internally instead.
35
+ - A cloud-server parallel of `get_tree` is a follow-up (it needs a Postgres-store traversal); v1 is local, where the primary consumer (the show-tree skill) runs.
36
+
37
+ No entity, domain, region, playbook, framework, or edge-count change (entities 315, edges 980, tools 121).
38
+
39
+ ---
40
+
10
41
  ## [0.9.14] - 2026-06-11
11
42
 
12
43
  **Introspection completeness: make the live surface complete and honest so clients can stop hardcoding.** A diagnostic of the skill suite found shared docs pointing skills at an introspection field that did not exist, two redundant status fields, a silent mis-parenting path, and four expected frameworks that hard-errored. This release closes those gaps.
package/dist/index.cjs CHANGED
@@ -44,6 +44,8 @@ __export(index_exports, {
44
44
  UPG_ANTI_PATTERNS: () => UPG_ANTI_PATTERNS,
45
45
  UPG_APPROACHES: () => UPG_APPROACHES,
46
46
  UPG_APPROACHES_BY_ID: () => UPG_APPROACHES_BY_ID,
47
+ UPG_AREA_TAXONOMY: () => UPG_AREA_TAXONOMY,
48
+ UPG_AREA_TAXONOMY_BY_COVERAGE_KEY: () => UPG_AREA_TAXONOMY_BY_COVERAGE_KEY,
47
49
  UPG_CANONICAL_FORMAT_VERSION: () => UPG_CANONICAL_FORMAT_VERSION,
48
50
  UPG_CONTAINMENT_FREE_TYPES: () => UPG_CONTAINMENT_FREE_TYPES,
49
51
  UPG_COUNT_BENCHMARKS: () => UPG_COUNT_BENCHMARKS,
@@ -91,6 +93,8 @@ __export(index_exports, {
91
93
  UPG_SPLIT_MIGRATIONS: () => UPG_SPLIT_MIGRATIONS,
92
94
  UPG_STATUS_MIGRATIONS: () => UPG_STATUS_MIGRATIONS,
93
95
  UPG_STRUCTURE_PATTERNS: () => UPG_STRUCTURE_PATTERNS,
96
+ UPG_TREE_PATTERNS: () => UPG_TREE_PATTERNS,
97
+ UPG_TREE_PATTERNS_BY_ID: () => UPG_TREE_PATTERNS_BY_ID,
94
98
  UPG_TYPES: () => UPG_TYPES,
95
99
  UPG_TYPES_SET: () => UPG_TYPES_SET,
96
100
  UPG_TYPE_ALIASES: () => UPG_TYPE_ALIASES,
@@ -119,9 +123,12 @@ __export(index_exports, {
119
123
  getAntiPatterns: () => getAntiPatterns,
120
124
  getAntiPatternsBySeverity: () => getAntiPatternsBySeverity,
121
125
  getAntiPatternsForStage: () => getAntiPatternsForStage,
126
+ getAreaTaxonomyEntry: () => getAreaTaxonomyEntry,
122
127
  getBenchmark: () => getBenchmark,
123
128
  getBenchmarksByDomain: () => getBenchmarksByDomain,
129
+ getBusinessAreasForRegion: () => getBusinessAreasForRegion,
124
130
  getCanonicalPlaybookForRegion: () => getCanonicalPlaybookForRegion,
131
+ getCoverageKeysForRegion: () => getCoverageKeysForRegion,
125
132
  getDefaultLens: () => getDefaultLens,
126
133
  getDeprecatedTypes: () => getDeprecatedTypes,
127
134
  getDomainForType: () => getDomainForType,
@@ -149,6 +156,7 @@ __export(index_exports, {
149
156
  getRingForDomain: () => getRingForDomain,
150
157
  getScale: () => getScale,
151
158
  getSplitMigrations: () => getSplitMigrations,
159
+ getTreePattern: () => getTreePattern,
152
160
  getTypeId: () => getTypeId,
153
161
  getTypeName: () => getTypeName,
154
162
  getTypes: () => getTypes,
@@ -19862,6 +19870,140 @@ function buildTypeAliases() {
19862
19870
  }
19863
19871
  var UPG_TYPE_ALIASES = buildTypeAliases();
19864
19872
 
19873
+ // src/presentation/tree-patterns.ts
19874
+ var UPG_TREE_PATTERNS = [
19875
+ {
19876
+ id: "ost",
19877
+ label: "Opportunity Solution Tree",
19878
+ description: "A desired outcome branching into the opportunities under it and the solutions that address them (Teresa Torres).",
19879
+ framework_id: "opportunity-solution-tree",
19880
+ anchor_type: "outcome",
19881
+ fallback_anchors: ["desired_outcome", "opportunity"],
19882
+ child_map: {
19883
+ outcome: ["opportunity"],
19884
+ desired_outcome: ["opportunity"],
19885
+ opportunity: ["solution"]
19886
+ },
19887
+ natural_depth: 3
19888
+ },
19889
+ {
19890
+ id: "okr",
19891
+ label: "Objectives and Key Results",
19892
+ description: "Strategic themes containing objectives, each measured by its key results (John Doerr).",
19893
+ framework_id: "okr-framework",
19894
+ anchor_type: "strategic_theme",
19895
+ fallback_anchors: ["objective"],
19896
+ child_map: {
19897
+ strategic_theme: ["objective"],
19898
+ objective: ["key_result"]
19899
+ },
19900
+ natural_depth: 3
19901
+ },
19902
+ {
19903
+ id: "user",
19904
+ label: "User chain",
19905
+ description: "A persona and the jobs it pursues, branching into the needs and desired outcomes behind them.",
19906
+ anchor_type: "persona",
19907
+ fallback_anchors: ["job"],
19908
+ child_map: {
19909
+ persona: ["job", "need", "desired_outcome"],
19910
+ job: ["need", "desired_outcome"]
19911
+ },
19912
+ natural_depth: 3
19913
+ },
19914
+ {
19915
+ id: "product",
19916
+ label: "Product breakdown",
19917
+ description: "The product organised into feature areas, then features, epics, and user stories.",
19918
+ anchor_type: "product",
19919
+ fallback_anchors: ["feature_area", "feature"],
19920
+ child_map: {
19921
+ product: ["feature_area"],
19922
+ feature_area: ["feature"],
19923
+ feature: ["epic"],
19924
+ epic: ["user_story"]
19925
+ },
19926
+ natural_depth: 5
19927
+ },
19928
+ {
19929
+ id: "validation",
19930
+ label: "Validation chain",
19931
+ description: "A hypothesis through its experiment plan, experiment, run, and the learning it produced.",
19932
+ framework_id: "build-measure-learn",
19933
+ anchor_type: "hypothesis",
19934
+ fallback_anchors: ["experiment_plan", "experiment"],
19935
+ child_map: {
19936
+ hypothesis: ["experiment_plan"],
19937
+ experiment_plan: ["experiment"],
19938
+ experiment: ["experiment_run"],
19939
+ experiment_run: ["learning"]
19940
+ },
19941
+ natural_depth: 5
19942
+ },
19943
+ {
19944
+ id: "strategy",
19945
+ label: "Strategy cascade",
19946
+ description: "Vision and mission into the strategic themes (bets), the initiatives that pursue them, and the outcomes they drive. Themes anchor on vision OR the product, whichever the graph wired.",
19947
+ anchor_type: "vision",
19948
+ fallback_anchors: ["product", "strategic_theme"],
19949
+ child_map: {
19950
+ vision: ["mission", "strategic_theme"],
19951
+ product: ["strategic_theme"],
19952
+ mission: ["strategic_theme"],
19953
+ strategic_theme: ["initiative"],
19954
+ initiative: ["outcome"]
19955
+ },
19956
+ natural_depth: 4
19957
+ },
19958
+ {
19959
+ id: "feature_areas",
19960
+ label: "Feature areas",
19961
+ description: "Feature areas and the features they contain.",
19962
+ anchor_type: "feature_area",
19963
+ fallback_anchors: ["feature"],
19964
+ child_map: {
19965
+ feature_area: ["feature"]
19966
+ },
19967
+ natural_depth: 2
19968
+ }
19969
+ ];
19970
+ var UPG_TREE_PATTERNS_BY_ID = Object.fromEntries(
19971
+ UPG_TREE_PATTERNS.map((p) => [p.id, p])
19972
+ );
19973
+ function getTreePattern(id) {
19974
+ return UPG_TREE_PATTERNS_BY_ID[id];
19975
+ }
19976
+
19977
+ // src/presentation/area-taxonomy.ts
19978
+ var UPG_AREA_TAXONOMY = [
19979
+ { coverage_key: "identity", label: "Identity", business_area: "identity", regions: ["strategy_outcomes"] },
19980
+ { coverage_key: "understanding", label: "Understanding", business_area: "understanding", regions: ["users_needs", "discovery_research_validation"] },
19981
+ { coverage_key: "discovery", label: "Discovery", business_area: "discovery", regions: ["discovery_research_validation", "market_competitive"] },
19982
+ { coverage_key: "validation", label: "Validation", business_area: null, regions: ["discovery_research_validation"] },
19983
+ { coverage_key: "reaching", label: "Reaching", business_area: "reaching", regions: ["business_gtm_growth"] },
19984
+ { coverage_key: "converting", label: "Converting", business_area: "converting", regions: ["business_gtm_growth"] },
19985
+ { coverage_key: "building", label: "Building", business_area: "building", regions: ["product_delivery", "experience_design_brand"] },
19986
+ { coverage_key: "sustaining", label: "Sustaining", business_area: "sustaining", regions: ["business_gtm_growth"] },
19987
+ { coverage_key: "learning", label: "Learning", business_area: "learning", regions: ["strategy_outcomes", "analytics_data", "operations_quality"] },
19988
+ { coverage_key: "operations", label: "Operations", business_area: null, regions: ["operations_quality"] }
19989
+ ];
19990
+ var UPG_AREA_TAXONOMY_BY_COVERAGE_KEY = Object.fromEntries(UPG_AREA_TAXONOMY.map((e) => [e.coverage_key, e]));
19991
+ function getAreaTaxonomyEntry(coverageKey) {
19992
+ return UPG_AREA_TAXONOMY_BY_COVERAGE_KEY[coverageKey];
19993
+ }
19994
+ function getCoverageKeysForRegion(regionId) {
19995
+ return UPG_AREA_TAXONOMY.filter((e) => e.regions.includes(regionId)).map((e) => e.coverage_key);
19996
+ }
19997
+ function getBusinessAreasForRegion(regionId) {
19998
+ const out = [];
19999
+ for (const e of UPG_AREA_TAXONOMY) {
20000
+ if (e.regions.includes(regionId) && e.business_area && !out.includes(e.business_area)) {
20001
+ out.push(e.business_area);
20002
+ }
20003
+ }
20004
+ return out;
20005
+ }
20006
+
19865
20007
  // src/playbooks/definitions/index.ts
19866
20008
  function seqStep(order, phase, entity_types, prompt_hint, options) {
19867
20009
  return {
@@ -28135,7 +28277,7 @@ function isCanonical(text) {
28135
28277
  }
28136
28278
 
28137
28279
  // src/index.ts
28138
- var UPG_VERSION = "0.9.14";
28280
+ var UPG_VERSION = "0.9.16";
28139
28281
  var UPG_FORMAT_VERSION = "0.4.0";
28140
28282
  var MARKDOWN_FORMAT_VERSION = "0.1";
28141
28283
  var UPG_TYPES = getTypes();
@@ -28224,6 +28366,8 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
28224
28366
  UPG_ANTI_PATTERNS,
28225
28367
  UPG_APPROACHES,
28226
28368
  UPG_APPROACHES_BY_ID,
28369
+ UPG_AREA_TAXONOMY,
28370
+ UPG_AREA_TAXONOMY_BY_COVERAGE_KEY,
28227
28371
  UPG_CANONICAL_FORMAT_VERSION,
28228
28372
  UPG_CONTAINMENT_FREE_TYPES,
28229
28373
  UPG_COUNT_BENCHMARKS,
@@ -28271,6 +28415,8 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
28271
28415
  UPG_SPLIT_MIGRATIONS,
28272
28416
  UPG_STATUS_MIGRATIONS,
28273
28417
  UPG_STRUCTURE_PATTERNS,
28418
+ UPG_TREE_PATTERNS,
28419
+ UPG_TREE_PATTERNS_BY_ID,
28274
28420
  UPG_TYPES,
28275
28421
  UPG_TYPES_SET,
28276
28422
  UPG_TYPE_ALIASES,
@@ -28299,9 +28445,12 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
28299
28445
  getAntiPatterns,
28300
28446
  getAntiPatternsBySeverity,
28301
28447
  getAntiPatternsForStage,
28448
+ getAreaTaxonomyEntry,
28302
28449
  getBenchmark,
28303
28450
  getBenchmarksByDomain,
28451
+ getBusinessAreasForRegion,
28304
28452
  getCanonicalPlaybookForRegion,
28453
+ getCoverageKeysForRegion,
28305
28454
  getDefaultLens,
28306
28455
  getDeprecatedTypes,
28307
28456
  getDomainForType,
@@ -28329,6 +28478,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
28329
28478
  getRingForDomain,
28330
28479
  getScale,
28331
28480
  getSplitMigrations,
28481
+ getTreePattern,
28332
28482
  getTypeId,
28333
28483
  getTypeName,
28334
28484
  getTypes,