@unified-product-graph/core 0.9.14 → 0.9.15

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,22 @@ This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [0.9.15] - 2026-06-11
11
+
12
+ **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.
13
+
14
+ ### Added
15
+ - **`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.
16
+ - **`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.
17
+
18
+ ### Notes
19
+ - `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.
20
+ - 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.
21
+
22
+ No entity, domain, region, playbook, framework, or edge-count change (entities 315, edges 980, tools 121).
23
+
24
+ ---
25
+
10
26
  ## [0.9.14] - 2026-06-11
11
27
 
12
28
  **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
@@ -91,6 +91,8 @@ __export(index_exports, {
91
91
  UPG_SPLIT_MIGRATIONS: () => UPG_SPLIT_MIGRATIONS,
92
92
  UPG_STATUS_MIGRATIONS: () => UPG_STATUS_MIGRATIONS,
93
93
  UPG_STRUCTURE_PATTERNS: () => UPG_STRUCTURE_PATTERNS,
94
+ UPG_TREE_PATTERNS: () => UPG_TREE_PATTERNS,
95
+ UPG_TREE_PATTERNS_BY_ID: () => UPG_TREE_PATTERNS_BY_ID,
94
96
  UPG_TYPES: () => UPG_TYPES,
95
97
  UPG_TYPES_SET: () => UPG_TYPES_SET,
96
98
  UPG_TYPE_ALIASES: () => UPG_TYPE_ALIASES,
@@ -149,6 +151,7 @@ __export(index_exports, {
149
151
  getRingForDomain: () => getRingForDomain,
150
152
  getScale: () => getScale,
151
153
  getSplitMigrations: () => getSplitMigrations,
154
+ getTreePattern: () => getTreePattern,
152
155
  getTypeId: () => getTypeId,
153
156
  getTypeName: () => getTypeName,
154
157
  getTypes: () => getTypes,
@@ -19862,6 +19865,110 @@ function buildTypeAliases() {
19862
19865
  }
19863
19866
  var UPG_TYPE_ALIASES = buildTypeAliases();
19864
19867
 
19868
+ // src/presentation/tree-patterns.ts
19869
+ var UPG_TREE_PATTERNS = [
19870
+ {
19871
+ id: "ost",
19872
+ label: "Opportunity Solution Tree",
19873
+ description: "A desired outcome branching into the opportunities under it and the solutions that address them (Teresa Torres).",
19874
+ framework_id: "opportunity-solution-tree",
19875
+ anchor_type: "outcome",
19876
+ fallback_anchors: ["desired_outcome", "opportunity"],
19877
+ child_map: {
19878
+ outcome: ["opportunity"],
19879
+ desired_outcome: ["opportunity"],
19880
+ opportunity: ["solution"]
19881
+ },
19882
+ natural_depth: 3
19883
+ },
19884
+ {
19885
+ id: "okr",
19886
+ label: "Objectives and Key Results",
19887
+ description: "Strategic themes containing objectives, each measured by its key results (John Doerr).",
19888
+ framework_id: "okr-framework",
19889
+ anchor_type: "strategic_theme",
19890
+ fallback_anchors: ["objective"],
19891
+ child_map: {
19892
+ strategic_theme: ["objective"],
19893
+ objective: ["key_result"]
19894
+ },
19895
+ natural_depth: 3
19896
+ },
19897
+ {
19898
+ id: "user",
19899
+ label: "User chain",
19900
+ description: "A persona and the jobs it pursues, branching into the needs and desired outcomes behind them.",
19901
+ anchor_type: "persona",
19902
+ fallback_anchors: ["job"],
19903
+ child_map: {
19904
+ persona: ["job", "need", "desired_outcome"],
19905
+ job: ["need", "desired_outcome"]
19906
+ },
19907
+ natural_depth: 3
19908
+ },
19909
+ {
19910
+ id: "product",
19911
+ label: "Product breakdown",
19912
+ description: "The product organised into feature areas, then features, epics, and user stories.",
19913
+ anchor_type: "product",
19914
+ fallback_anchors: ["feature_area", "feature"],
19915
+ child_map: {
19916
+ product: ["feature_area"],
19917
+ feature_area: ["feature"],
19918
+ feature: ["epic"],
19919
+ epic: ["user_story"]
19920
+ },
19921
+ natural_depth: 5
19922
+ },
19923
+ {
19924
+ id: "validation",
19925
+ label: "Validation chain",
19926
+ description: "A hypothesis through its experiment plan, experiment, run, and the learning it produced.",
19927
+ framework_id: "build-measure-learn",
19928
+ anchor_type: "hypothesis",
19929
+ fallback_anchors: ["experiment_plan", "experiment"],
19930
+ child_map: {
19931
+ hypothesis: ["experiment_plan"],
19932
+ experiment_plan: ["experiment"],
19933
+ experiment: ["experiment_run"],
19934
+ experiment_run: ["learning"]
19935
+ },
19936
+ natural_depth: 5
19937
+ },
19938
+ {
19939
+ id: "strategy",
19940
+ label: "Strategy cascade",
19941
+ 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.",
19942
+ anchor_type: "vision",
19943
+ fallback_anchors: ["product", "strategic_theme"],
19944
+ child_map: {
19945
+ vision: ["mission", "strategic_theme"],
19946
+ product: ["strategic_theme"],
19947
+ mission: ["strategic_theme"],
19948
+ strategic_theme: ["initiative"],
19949
+ initiative: ["outcome"]
19950
+ },
19951
+ natural_depth: 4
19952
+ },
19953
+ {
19954
+ id: "feature_areas",
19955
+ label: "Feature areas",
19956
+ description: "Feature areas and the features they contain.",
19957
+ anchor_type: "feature_area",
19958
+ fallback_anchors: ["feature"],
19959
+ child_map: {
19960
+ feature_area: ["feature"]
19961
+ },
19962
+ natural_depth: 2
19963
+ }
19964
+ ];
19965
+ var UPG_TREE_PATTERNS_BY_ID = Object.fromEntries(
19966
+ UPG_TREE_PATTERNS.map((p) => [p.id, p])
19967
+ );
19968
+ function getTreePattern(id) {
19969
+ return UPG_TREE_PATTERNS_BY_ID[id];
19970
+ }
19971
+
19865
19972
  // src/playbooks/definitions/index.ts
19866
19973
  function seqStep(order, phase, entity_types, prompt_hint, options) {
19867
19974
  return {
@@ -28135,7 +28242,7 @@ function isCanonical(text) {
28135
28242
  }
28136
28243
 
28137
28244
  // src/index.ts
28138
- var UPG_VERSION = "0.9.14";
28245
+ var UPG_VERSION = "0.9.15";
28139
28246
  var UPG_FORMAT_VERSION = "0.4.0";
28140
28247
  var MARKDOWN_FORMAT_VERSION = "0.1";
28141
28248
  var UPG_TYPES = getTypes();
@@ -28271,6 +28378,8 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
28271
28378
  UPG_SPLIT_MIGRATIONS,
28272
28379
  UPG_STATUS_MIGRATIONS,
28273
28380
  UPG_STRUCTURE_PATTERNS,
28381
+ UPG_TREE_PATTERNS,
28382
+ UPG_TREE_PATTERNS_BY_ID,
28274
28383
  UPG_TYPES,
28275
28384
  UPG_TYPES_SET,
28276
28385
  UPG_TYPE_ALIASES,
@@ -28329,6 +28438,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
28329
28438
  getRingForDomain,
28330
28439
  getScale,
28331
28440
  getSplitMigrations,
28441
+ getTreePattern,
28332
28442
  getTypeId,
28333
28443
  getTypeName,
28334
28444
  getTypes,