@unified-product-graph/core 0.22.1 → 0.23.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/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  The TypeScript core for the **Unified Product Graph (UPG)**, an open specification that gives product tools a shared vocabulary for entities, edges, and frameworks.
9
9
 
10
- 320 entity types across 37 domains. 1039 typed edges. 46 canonical framework definitions, with more added as each is reviewed.
10
+ 320 entity types across 37 domains. 1041 typed edges. 46 canonical framework definitions, with more added as each is reviewed.
11
11
 
12
12
  ## Install
13
13
 
package/dist/index.cjs CHANGED
@@ -1684,6 +1684,17 @@ var UPG_EDGE_CATALOG = {
1684
1684
  bug_affects_feature: { forward_verb: "affects", reverse_verb: "affected_by", classification: "cross-domain", source_type: "bug", target_type: "feature" },
1685
1685
  roadmap_item_references_feature: { forward_verb: "references", reverse_verb: "referenced_by", classification: "cross-domain", source_type: "roadmap_item", target_type: "feature" },
1686
1686
  feature_decomposes_into_task: { forward_verb: "decomposes_into", reverse_verb: "implements", classification: "hierarchy", source_type: "feature", target_type: "task" },
1687
+ // Epic-level mirrors of the feature→task / feature→bug hierarchy (feedback
1688
+ // df99026a). A `feature` is the flat planning root, but an `epic` is a body of
1689
+ // work under it, and real imported ticket sets (Linear/Jira) carry bugs and
1690
+ // pure engineering tasks that belong to ONE epic, not the feature as a whole.
1691
+ // Without these, such tickets had to be mislabelled `user_story` (the only
1692
+ // epic child) to keep the epic grouping. These are additive twins of the
1693
+ // feature-level edges (same verbs/classification), so `pickCanonicalEdge` /
1694
+ // `resolveContainmentEdge('epic', 'task'|'bug')` and the adapter import path
1695
+ // resolve them with no further wiring.
1696
+ epic_decomposes_into_task: { forward_verb: "decomposes_into", reverse_verb: "implements", classification: "hierarchy", source_type: "epic", target_type: "task" },
1697
+ epic_affected_by_bug: { forward_verb: "affected_by", reverse_verb: "affects", classification: "hierarchy", source_type: "epic", target_type: "bug" },
1687
1698
  task_has_subtask: { forward_verb: "has_subtask", reverse_verb: "is_subtask_of", classification: "hierarchy", source_type: "task", target_type: "task" },
1688
1699
  // ── Planning cadence (0.20.0) ────────────────────────────────────────────────
1689
1700
  // The cadence axis. E1 self-nests the interval (a program-increment contains
@@ -3987,7 +3998,10 @@ var UPG_VALID_CHILDREN = {
3987
3998
  // task_implements_user_story edge.
3988
3999
  feature: ["epic", "bug", "task"],
3989
4000
  feature_area: ["feature", "feature_area"],
3990
- epic: ["user_story"],
4001
+ // epic owns user_story (the templated promise) and, mirroring feature, may
4002
+ // also directly contain bug/task — heterogeneous imported tickets that belong
4003
+ // to one epic rather than the feature as a whole (feedback df99026a).
4004
+ epic: ["user_story", "bug", "task"],
3991
4005
  user_story: ["acceptance_criterion"],
3992
4006
  task: ["task"],
3993
4007
  // planning_cycle (0.20.0): the cadence axis self-nests (a program-increment
@@ -10972,7 +10986,7 @@ var UPG_PROPERTY_SCHEMA = {
10972
10986
  },
10973
10987
  // DashboardProperties: Dashboard entity.
10974
10988
  dashboard: {
10975
- tool: { type: "string", enum: ["looker", "amplitude", "mixpanel", "posthog", "custom"], description: "Analytics tool hosting this dashboard" },
10989
+ tool: { type: "string", enum: ["looker", "amplitude", "mixpanel", "posthog", "omni", "custom"], description: "Analytics tool hosting this dashboard" },
10976
10990
  url: { type: "string", description: "URL to the live dashboard", modifier: "volatile" },
10977
10991
  audience: { type: "string", description: "Intended audience for this dashboard" },
10978
10992
  element_count: { type: "number", description: "Number of widgets or panels on the dashboard", modifier: "derived" },
@@ -23131,6 +23145,12 @@ var PRODUCT_SPEC_GUIDE = {
23131
23145
  entity_types: ["feature_area", "feature", "epic", "user_story", "task"],
23132
23146
  edge_chain: ["feature_area_contains_feature", "feature_decomposed_into_epic", "epic_specified_by_user_story", "task_implements_user_story"]
23133
23147
  },
23148
+ {
23149
+ name: "Epic Work Items",
23150
+ description: "A bug or a pure engineering/infra task that belongs to one specific epic (not the feature as a whole) attaches directly to that epic, mirroring how task and bug attach at the feature level. Use this when importing a real tracker (Linear/Jira) whose tickets are heterogeneous: keep genuine stories as user_story, but let bugs, spikes, and engineering tasks nest under their epic with their true type instead of being mislabelled to preserve the grouping.",
23151
+ entity_types: ["epic", "task", "bug"],
23152
+ edge_chain: ["epic_decomposes_into_task", "epic_affected_by_bug"]
23153
+ },
23134
23154
  {
23135
23155
  name: "Planning Cadence",
23136
23156
  description: "The cadence axis. Create a planning_cycle (a sprint, iteration, quarter, or PI), nest finer cycles inside a coarse one, schedule the stories that flow through it, and scope the objectives the cycle serves. Scheduling and scoping are deliberate links, not containment: a story keeps its feature/epic parent.",
@@ -29947,7 +29967,7 @@ function isCanonical(text) {
29947
29967
  }
29948
29968
 
29949
29969
  // src/index.ts
29950
- var UPG_VERSION = "0.22.1";
29970
+ var UPG_VERSION = "0.23.0";
29951
29971
  var UPG_FORMAT_VERSION = "0.4.0";
29952
29972
  var MARKDOWN_FORMAT_VERSION = "0.1";
29953
29973
  var UPG_TYPES = getTypes();