@unified-product-graph/mcp-server 0.6.3 → 0.7.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/dist/index.js CHANGED
@@ -160,7 +160,7 @@ var UPG_DOMAINS = [
160
160
  "feature",
161
161
  "feature_area",
162
162
  "epic",
163
- "story_statement",
163
+ "user_story",
164
164
  "acceptance_criterion",
165
165
  "release",
166
166
  "task",
@@ -677,20 +677,19 @@ var UPG_ENTITY_META = [
677
677
  { name: "feature_area", type_id: "ent_314", maturity: "stable", since: "0.1.0" },
678
678
  { name: "feature", type_id: "ent_071", maturity: "stable", since: "0.1.0" },
679
679
  { name: "epic", type_id: "ent_072", maturity: "stable", since: "0.1.0" },
680
- // split 2 (v0.2.7): `user_story` decomposes into `story_statement`
681
- // (P5 templated-statement, lifecycle-free design artefact) +
682
- // `story_task` (P4 work-unit, the engineering work to implement). The
683
- // statement is the "As X, I want Y so Z" stable promise; the task carries
684
- // the lifecycle (backlog in_progress done). Replacement points to
685
- // `story_task` because legacy user_story rows almost always carried task
686
- // properties (assignee, status, priority); the statement is additive
687
- // structural surface. Narrows to `never` in v0.2.9.
688
- // user_story story_task was the v0.2.7 migration. story_task is now
689
- // deprecated at v0.4.0 and collapsed into canonical `task`. story_task carried
690
- // no unique properties or lifecycle that task doesn't already carry, so the
691
- // additive-vocabulary rule keeps one.
692
- { name: "user_story", type_id: "ent_073", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.2.7", replacement: "task" },
693
- { name: "story_statement", type_id: "ent_342", maturity: "proposed", since: "0.2.7" },
680
+ // `user_story` is the templated "As X, I want Y so Z" promise — a stable,
681
+ // lifecycle-free design artefact (UCS pattern P5). The v0.2.7 split EXTRACTED
682
+ // the engineering work into a separate `task` (the lifecycle-bearing work-unit,
683
+ // linked via `task_implements_user_story`); the split was right. But the
684
+ // surviving statement half was renamed to the coined `story_statement`, which
685
+ // raised the adoption barrier "user story" is the universally-recognised
686
+ // industry term for exactly this artefact. v0.7.0 (UPG-571) re-canonicalises
687
+ // the statement under `user_story`; `story_statement` becomes a deprecated
688
+ // alias. `story_task` (the original work half) was already collapsed into
689
+ // canonical `task` at v0.4.0. So the canonical shape is: user_story (statement)
690
+ // + task (work), linked by `task_implements_user_story`.
691
+ { name: "user_story", type_id: "ent_073", maturity: "proposed", since: "0.1.0" },
692
+ { name: "story_statement", type_id: "ent_342", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.7.0", replacement: "user_story" },
694
693
  { name: "story_task", type_id: "ent_343", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.4.0", replacement: "task" },
695
694
  { name: "acceptance_criterion", type_id: "ent_074", maturity: "stable", since: "0.1.0" },
696
695
  { name: "release", type_id: "ent_075", maturity: "stable", since: "0.1.0" },
@@ -1261,16 +1260,15 @@ var UPG_EDGE_CATALOG = {
1261
1260
  outcome_delivered_by_feature: { forward_verb: "delivered_by", reverse_verb: "delivers", classification: "cross-domain", source_type: "outcome", target_type: "feature" },
1262
1261
  outcome_delivered_via_feature_area: { forward_verb: "delivered_via", reverse_verb: "delivers_for", classification: "cross-domain", source_type: "outcome", target_type: "feature_area" },
1263
1262
  feature_decomposed_into_epic: { forward_verb: "decomposed_into", reverse_verb: "implements", classification: "hierarchy", source_type: "feature", target_type: "epic" },
1264
- // user_story → story_statement (P5 templated-statement,
1265
- // lifecycle-free design artefact) + story_task (P4 work-unit, the engineering
1266
- // work). Statement carries the "As X, I want Y so Z" stable promise + verifies
1267
- // through acceptance criteria + is covered by test cases + is targeted by
1268
- // epics; task carries the lifecycle and the implementation work.
1269
- epic_specified_by_story_statement: { forward_verb: "specified_by", reverse_verb: "specifies", classification: "hierarchy", source_type: "epic", target_type: "story_statement" },
1270
- story_statement_verified_by_acceptance_criterion: { forward_verb: "verified_by", reverse_verb: "verifies", classification: "hierarchy", source_type: "story_statement", target_type: "acceptance_criterion" },
1271
- // story_task collapsed into task. Edge renamed accordingly.
1272
- // UPG_EDGE_MIGRATIONS['0.4.0'] carries the rename rule for old graphs.
1273
- task_implements_story_statement: { forward_verb: "implements", reverse_verb: "implemented_by", classification: "cross-domain", source_type: "task", target_type: "story_statement" },
1263
+ // user_story (P5 templated-statement, the "As X, I want Y so Z" lifecycle-free
1264
+ // promise) verifies through acceptance criteria, is covered by test cases, and
1265
+ // is specified by epics; the paired `task` carries the lifecycle and the
1266
+ // implementation work, and implements the statement. (v0.2.7 split extracted
1267
+ // the work into `task`; v0.7.0/UPG-571 re-canonicalised the statement
1268
+ // story_statement user_story see UPG_EDGE_MIGRATIONS['0.7.0'].)
1269
+ epic_specified_by_user_story: { forward_verb: "specified_by", reverse_verb: "specifies", classification: "hierarchy", source_type: "epic", target_type: "user_story" },
1270
+ user_story_verified_by_acceptance_criterion: { forward_verb: "verified_by", reverse_verb: "verifies", classification: "hierarchy", source_type: "user_story", target_type: "acceptance_criterion" },
1271
+ task_implements_user_story: { forward_verb: "implements", reverse_verb: "implemented_by", classification: "cross-domain", source_type: "task", target_type: "user_story" },
1274
1272
  feature_affected_by_bug: { forward_verb: "affected_by", reverse_verb: "affects", classification: "hierarchy", source_type: "feature", target_type: "bug" },
1275
1273
  // release containment edges — used by the GitHub adapter when
1276
1274
  // importing milestone→issue relationships. resolveContainmentEdge('release',
@@ -1286,10 +1284,10 @@ var UPG_EDGE_CATALOG = {
1286
1284
  // feature_area is not contained by theme — themes span multiple
1287
1285
  // areas cross-cuttingly. Containment path: product → feature_area.
1288
1286
  theme_spans_feature_area: { forward_verb: "spans", reverse_verb: "spanned_by", classification: "semantic", source_type: "theme", target_type: "feature_area" },
1289
- // `task_implements_user_story` consolidated into the
1290
- // canonical `story_task_implements_story_statement` above. The legacy
1291
- // task→user_story edge is no longer registered story_task IS the task,
1292
- // and statements carry the implements relationship directly.
1287
+ // The legacy `story_task` collapsed into `task` (v0.4.0), so the implements
1288
+ // relationship is the canonical `task_implements_user_story` above there is
1289
+ // no separate story_task edge. (v0.2.7 introduced the Statement/Implementation
1290
+ // split; v0.7.0/UPG-571 re-canonicalised the statement to user_story.)
1293
1291
  bug_affects_feature: { forward_verb: "affects", reverse_verb: "affected_by", classification: "cross-domain", source_type: "bug", target_type: "feature" },
1294
1292
  roadmap_item_references_feature: { forward_verb: "references", reverse_verb: "referenced_by", classification: "cross-domain", source_type: "roadmap_item", target_type: "feature" },
1295
1293
  feature_decomposes_into_task: { forward_verb: "decomposes_into", reverse_verb: "implements", classification: "hierarchy", source_type: "feature", target_type: "task" },
@@ -1539,7 +1537,7 @@ var UPG_EDGE_CATALOG = {
1539
1537
  test_suite_covers_feature: { forward_verb: "covers", reverse_verb: "covered_by", classification: "cross-domain", source_type: "test_suite", target_type: "feature" },
1540
1538
  test_environment_mirrors_deployment: { forward_verb: "mirrors", reverse_verb: "mirrored_by", classification: "cross-domain", source_type: "test_environment", target_type: "deployment" },
1541
1539
  regression_test_guards_release: { forward_verb: "guards", reverse_verb: "guarded_by", classification: "cross-domain", source_type: "regression_test", target_type: "release" },
1542
- test_case_covers_story_statement: { forward_verb: "covers", reverse_verb: "covered_by", classification: "cross-domain", source_type: "test_case", target_type: "story_statement" },
1540
+ test_case_covers_user_story: { forward_verb: "covers", reverse_verb: "covered_by", classification: "cross-domain", source_type: "test_case", target_type: "user_story" },
1543
1541
  qa_session_targets_feature: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "qa_session", target_type: "feature" },
1544
1542
  test_coverage_report_covers_service: { forward_verb: "covers", reverse_verb: "covered_by", classification: "cross-domain", source_type: "test_coverage_report", target_type: "service" },
1545
1543
  test_suite_produces_test_result: { forward_verb: "produces", reverse_verb: "produced_by", classification: "causal", source_type: "test_suite", target_type: "test_result" },
@@ -3055,12 +3053,12 @@ var UPG_VALID_CHILDREN = {
3055
3053
  ],
3056
3054
  // ── Product Specification hierarchy ─────────────────────────────────────────
3057
3055
  // story_task collapsed into canonical task. feature now owns
3058
- // task directly; story-derived tasks implement story_statement via
3059
- // task_implements_story_statement edge.
3056
+ // task directly; story-derived tasks implement user_story via
3057
+ // task_implements_user_story edge.
3060
3058
  feature: ["epic", "bug", "task"],
3061
3059
  feature_area: ["feature", "feature_area"],
3062
- epic: ["story_statement"],
3063
- story_statement: ["acceptance_criterion"],
3060
+ epic: ["user_story"],
3061
+ user_story: ["acceptance_criterion"],
3064
3062
  task: ["task"],
3065
3063
  // ── Engineering hierarchy ───────────────────────────────────────────────────
3066
3064
  bounded_context: [
@@ -4178,37 +4176,6 @@ var EPIC_LIFECYCLE = {
4178
4176
  }
4179
4177
  ]
4180
4178
  };
4181
- var USER_STORY_LIFECYCLE = {
4182
- entity_type: "user_story",
4183
- initial_phase: "draft",
4184
- terminal_phases: ["done"],
4185
- phases: [
4186
- {
4187
- id: "draft",
4188
- label: "Draft",
4189
- description: "The story has been written but has not been reviewed or refined. It may not yet have acceptance criteria.",
4190
- transitions_to: ["ready"]
4191
- },
4192
- {
4193
- id: "ready",
4194
- label: "Ready",
4195
- description: "The story has been refined. Acceptance criteria are defined. It is ready to be pulled into a sprint.",
4196
- transitions_to: ["in_progress"]
4197
- },
4198
- {
4199
- id: "in_progress",
4200
- label: "In Progress",
4201
- description: "A developer is actively working on this story.",
4202
- transitions_to: ["done"]
4203
- },
4204
- {
4205
- id: "done",
4206
- label: "Done",
4207
- description: "The story meets all acceptance criteria and has been merged and verified.",
4208
- transitions_to: []
4209
- }
4210
- ]
4211
- };
4212
4179
  var RELEASE_LIFECYCLE = {
4213
4180
  entity_type: "release",
4214
4181
  initial_phase: "planned",
@@ -5709,9 +5676,9 @@ var UPG_LIFECYCLES = [
5709
5676
  FEATURE_AREA_LIFECYCLE,
5710
5677
  FEATURE_LIFECYCLE,
5711
5678
  EPIC_LIFECYCLE,
5712
- USER_STORY_LIFECYCLE,
5713
- // story_task lifecycle removed v0.4.0 collapsed story_task into task.
5714
- // task uses TASK_LIFECYCLE (WORK_ITEM_TEMPLATE) which is equivalent.
5679
+ // user_story is lifecycle-free (declared in UPG_LIFECYCLE_FREE_TYPES below).
5680
+ // story_task lifecycle removed v0.4.0 collapsed into task (TASK_LIFECYCLE,
5681
+ // WORK_ITEM_TEMPLATE).
5715
5682
  RELEASE_LIFECYCLE,
5716
5683
  TASK_LIFECYCLE,
5717
5684
  BUG_LIFECYCLE,
@@ -5818,12 +5785,13 @@ var UPG_LIFECYCLE_FREE_TYPES = /* @__PURE__ */ new Set([
5818
5785
  "brand_typography",
5819
5786
  "brand_imagery",
5820
5787
  // ── Product Specification (4 of 5) — criteria, grouping, historical, +
5821
- // story_statement (v0.2.7 split: the templated promise is a stable
5822
- // design artefact; the paired story_task carries the lifecycle)
5788
+ // user_story (the templated promise is a stable design artefact; the paired
5789
+ // task carries the lifecycle). Re-canon story_statement user_story at
5790
+ // v0.7.0/UPG-571. ─
5823
5791
  "acceptance_criterion",
5824
5792
  "changelog",
5825
5793
  "theme",
5826
- "story_statement",
5794
+ "user_story",
5827
5795
  // ── Strategy — metric is a measurement definition; metric_quality_assessment
5828
5796
  // is a point-in-time snapshot; value_stream is a mapped flow;
5829
5797
  // constraint carries its own `constraint_status` enum (binding/advisory/
@@ -6123,6 +6091,23 @@ var UPG_SCALES = {
6123
6091
  }
6124
6092
  };
6125
6093
  var UPG_MIGRATIONS = {
6094
+ "0.7.0": [
6095
+ // (since v0.7.0, UPG-571) story_statement → user_story. The v0.2.7 split
6096
+ // correctly separated the templated promise from the engineering work
6097
+ // (task), but renamed the surviving statement half to the coined
6098
+ // `story_statement`. "User story" is the universally-recognised industry
6099
+ // term for exactly that artefact, and UPG's value is being the recognisable
6100
+ // canonical vocabulary — so the statement is re-canonicalised under
6101
+ // `user_story`. Lifecycle-free, same property surface (as_a / i_want_to /
6102
+ // so_that / text); no property migration required. The paired `task` and
6103
+ // the `task_implements_*` / `epic_specified_by_*` / `*_verified_by_*` /
6104
+ // `test_case_covers_*` edges are renamed in UPG_EDGE_MIGRATIONS['0.7.0'].
6105
+ {
6106
+ from: "story_statement",
6107
+ to: "user_story",
6108
+ reason: 'story_statement re-canonicalised to user_story (UPG-571). The v0.2.7 Statement/Implementation split was sound \u2014 it extracted the lifecycle-bearing work into `task` \u2014 but the coined `story_statement` name raised the adoption barrier; "user story" is the industry-standard term for the templated promise. Lifecycle-free, identical property surface (as_a / i_want_to / so_that / text); no property migration needed.'
6109
+ }
6110
+ ],
6126
6111
  "0.4.0": [
6127
6112
  // (since v0.4.0) hypothesis_claim reverts to hypothesis (the simpler
6128
6113
  // canonical name — "claim" is implied). hypothesis_evidence deprecated
@@ -7062,6 +7047,18 @@ var UPG_SPLIT_MIGRATIONS = {
7062
7047
  ]
7063
7048
  };
7064
7049
  var UPG_EDGE_MIGRATIONS = {
7050
+ "0.7.0": [
7051
+ // (since v0.7.0, UPG-571) story_statement → user_story re-canon. The four
7052
+ // canonical edges that touch the statement are renamed to the user_story
7053
+ // form. Endpoint guards reference the POST-migration (user_story) types —
7054
+ // edge migration runs after node migration, so by the time these rules
7055
+ // apply the statement node has already been renamed story_statement →
7056
+ // user_story (UPG_MIGRATIONS['0.7.0']).
7057
+ { kind: "rename", from: "task_implements_story_statement", to: "task_implements_user_story", requires_source_type: "task", requires_target_type: "user_story", reason: "story_statement \u2192 user_story (UPG-571). Task still implements the statement; edge key updated to the re-canonicalised target type." },
7058
+ { kind: "rename", from: "epic_specified_by_story_statement", to: "epic_specified_by_user_story", requires_source_type: "epic", requires_target_type: "user_story", reason: "story_statement \u2192 user_story (UPG-571). Epics specify the statement; edge key updated to the re-canonicalised target type." },
7059
+ { kind: "rename", from: "story_statement_verified_by_acceptance_criterion", to: "user_story_verified_by_acceptance_criterion", requires_source_type: "user_story", requires_target_type: "acceptance_criterion", reason: "story_statement \u2192 user_story (UPG-571). Acceptance criteria verify the statement; edge key updated to the re-canonicalised source type." },
7060
+ { kind: "rename", from: "test_case_covers_story_statement", to: "test_case_covers_user_story", requires_source_type: "test_case", requires_target_type: "user_story", reason: "story_statement \u2192 user_story (UPG-571). Test cases cover the statement; edge key updated to the re-canonicalised target type." }
7061
+ ],
7065
7062
  "0.4.0": [
7066
7063
  // ── hypothesis_claim → hypothesis reverse rename ───────────────
7067
7064
  // Every edge that was renamed FROM hypothesis_* TO hypothesis_claim_* in
@@ -7542,18 +7539,19 @@ var UPG_EDGE_MIGRATIONS = {
7542
7539
  requires_target_type: "story_statement",
7543
7540
  reason: "Test cases cover the spec, not the work; retargets target to story_statement."
7544
7541
  },
7545
- // Two user_story-edges drop (consolidated into the new canonical
7546
- // story_task_implements_story_statement edge).
7542
+ // user_story_broken_into_task drops consolidated into the implements edge.
7547
7543
  {
7548
7544
  kind: "drop",
7549
7545
  from: "user_story_broken_into_task",
7550
- reason: 'Consolidated into the canonical story_task_implements_story_statement (the implements relationship now flows from task to statement directly). CHANGELOG v0.2.7: "user_story_broken_into_task \u2192 dropped; consolidated into story_task_implements_story_statement."'
7551
- },
7552
- {
7553
- kind: "drop",
7554
- from: "task_implements_user_story",
7555
- reason: 'Consolidated as above \u2014 story_task IS the task, statements carry the implements relationship directly. CHANGELOG v0.2.7: "task_implements_user_story \u2192 dropped; consolidated as above."'
7556
- }
7546
+ reason: 'Consolidated into the canonical implements edge (the relationship now flows from task to statement directly). CHANGELOG v0.2.7: "user_story_broken_into_task \u2192 dropped."'
7547
+ }
7548
+ // NOTE: the v0.2.7 drop of `task_implements_user_story` was REMOVED at v0.7.0
7549
+ // (UPG-571). Re-canonicalising story_statement → user_story makes
7550
+ // `task_implements_user_story` the canonical implements edge again, so the
7551
+ // name is no longer retired (a drop rule must never name a canonical edge).
7552
+ // Legacy pre-0.2.7 instances are reconnected by the v0.2.7 split's emitted
7553
+ // implements edge; any residual dangling edge is handled by
7554
+ // repair_dangling_edges.
7557
7555
  ],
7558
7556
  "0.2.8": [
7559
7557
  // ── split 3: 12 hypothesis-edge retargets + 1 drop ─────────────
@@ -10439,8 +10437,8 @@ var UPG_PROPERTY_SCHEMA = {
10439
10437
  risks_flagged: { type: "number", description: "Number of risks flagged in this report" },
10440
10438
  blockers: { type: "string", description: "Description of current blockers" }
10441
10439
  },
10442
- // StoryStatementProperties — "As X, I want Y so Z" templated promise on a user story (UCS pattern P5).
10443
- story_statement: {
10440
+ // UserStoryProperties — "As X, I want Y so Z" templated promise a user story (UCS pattern P5).
10441
+ user_story: {
10444
10442
  as_a: { type: "string", description: '"As a [persona], \u2026". Free-text persona name or slug ref.' },
10445
10443
  i_want_to: { type: "string", description: "Capability or action the persona wants." },
10446
10444
  so_that: { type: "string", description: "Benefit or outcome the persona expects." },
@@ -11000,7 +10998,7 @@ var UPG_FRAMEWORKS = [
11000
10998
  },
11001
10999
  {
11002
11000
  "label": "User Stories",
11003
- "entityTypeId": "story_statement",
11001
+ "entityTypeId": "user_story",
11004
11002
  "description": "Detailed stories prioritised vertically"
11005
11003
  },
11006
11004
  {
@@ -11020,7 +11018,7 @@ var UPG_FRAMEWORKS = [
11020
11018
  "role": "bucket"
11021
11019
  },
11022
11020
  {
11023
- "type": "story_statement",
11021
+ "type": "user_story",
11024
11022
  "role": "bucket"
11025
11023
  },
11026
11024
  {
@@ -15757,7 +15755,7 @@ var PRODUCT_DELIVERY_PLAYBOOK = {
15757
15755
  seqStep(
15758
15756
  3,
15759
15757
  "Stories",
15760
- ["story_statement", "acceptance_criterion"],
15758
+ ["user_story", "acceptance_criterion"],
15761
15759
  'Write each feature from the user perspective. "As [persona], I want [job], so that [outcome]." Define acceptance criteria.'
15762
15760
  ),
15763
15761
  seqStep(
@@ -17144,19 +17142,19 @@ var PRODUCT_SPEC_GUIDE = {
17144
17142
  // registered to product_spec but missing from the navigation order).
17145
17143
  // `changelog` lives here because it is a structural product-shipping
17146
17144
  // artefact; content domain references it only via cross-domain bridges.
17147
- creation_sequence: ["feature_area", "feature", "epic", "story_statement", "acceptance_criterion", "task", "bug", "release", "roadmap", "roadmap_item", "theme", "changelog"],
17145
+ creation_sequence: ["feature_area", "feature", "epic", "user_story", "acceptance_criterion", "task", "bug", "release", "roadmap", "roadmap_item", "theme", "changelog"],
17148
17146
  patterns: [
17149
17147
  {
17150
17148
  name: "Feature Decomposition",
17151
- description: "Features group into areas, decompose into epics, epics specify story_statements (the templated promise), and tasks implement statements as the engineering work",
17152
- entity_types: ["feature_area", "feature", "epic", "story_statement", "task"],
17153
- edge_chain: ["feature_area_contains_feature", "feature_decomposed_into_epic", "epic_specified_by_story_statement", "task_implements_story_statement"]
17149
+ description: "Features group into areas, decompose into epics, epics specify user stories (the templated promise), and tasks implement them as the engineering work",
17150
+ entity_types: ["feature_area", "feature", "epic", "user_story", "task"],
17151
+ edge_chain: ["feature_area_contains_feature", "feature_decomposed_into_epic", "epic_specified_by_user_story", "task_implements_user_story"]
17154
17152
  }
17155
17153
  ],
17156
17154
  required_bridges: [
17157
17155
  { edge_type: "feature_tests_hypothesis", target_domain: "validation", when: "Features should trace back to validated hypotheses" },
17158
17156
  { edge_type: "outcome_delivered_by_feature", target_domain: "strategy", when: "Every feature should connect to a strategic outcome" },
17159
- { edge_type: "test_case_covers_story_statement", target_domain: "testing", when: "Story statements should have acceptance tests" }
17157
+ { edge_type: "test_case_covers_user_story", target_domain: "testing", when: "User stories should have acceptance tests" }
17160
17158
  ],
17161
17159
  anti_patterns: [
17162
17160
  { description: "Features without outcomes. Features serve strategic outcomes; the rest is waste." },
@@ -17337,7 +17335,7 @@ var TESTING_GUIDE = {
17337
17335
  }
17338
17336
  ],
17339
17337
  required_bridges: [
17340
- { edge_type: "test_case_covers_story_statement", target_domain: "product_spec", when: "Test cases should trace back to story statements (which in turn trace to features via epics)" },
17338
+ { edge_type: "test_case_covers_user_story", target_domain: "product_spec", when: "Test cases should trace back to user stories (which in turn trace to features via epics)" },
17341
17339
  { edge_type: "test_case_validates_acceptance_criterion", target_domain: "product_spec", when: 'Acceptance criteria define what "done" means and must be validated by tests' }
17342
17340
  ],
17343
17341
  anti_patterns: [
@@ -18970,7 +18968,7 @@ var UPG_COUNT_BENCHMARKS = [
18970
18968
  "rationale": "Epics group related stories. Not needed at idea stage."
18971
18969
  },
18972
18970
  {
18973
- "type": "story_statement",
18971
+ "type": "user_story",
18974
18972
  "domain": "product_spec",
18975
18973
  "concept": null,
18976
18974
  "validation": {
@@ -19881,7 +19879,7 @@ var UPG_RATIO_BENCHMARKS = [
19881
19879
  },
19882
19880
  {
19883
19881
  "name": "Story coverage",
19884
- "numerator_type": "story_statement",
19882
+ "numerator_type": "user_story",
19885
19883
  "denominator_type": "feature",
19886
19884
  "expected_min": 2,
19887
19885
  "stages": [
@@ -21606,7 +21604,7 @@ var UPG_REGIONS = [
21606
21604
  "feature_affected_by_bug",
21607
21605
  "epic_specified_by_user_story",
21608
21606
  "user_story_verified_by_acceptance_criterion",
21609
- "user_story_broken_into_task",
21607
+ "task_implements_user_story",
21610
21608
  "roadmap_contains_roadmap_item",
21611
21609
  "roadmap_categorised_by_theme",
21612
21610
  "roadmap_schedules_release",
@@ -22471,6 +22469,8 @@ var UPG_FRAMEWORK_CATEGORIES = [
22471
22469
  // Engineering & Ops
22472
22470
  "engineering",
22473
22471
  "devops",
22472
+ "security",
22473
+ "qa_testing",
22474
22474
  "ai_ml",
22475
22475
  "agentic",
22476
22476
  // Growth & GTM
@@ -22479,12 +22479,17 @@ var UPG_FRAMEWORK_CATEGORIES = [
22479
22479
  "go_to_market",
22480
22480
  "sales",
22481
22481
  "pricing",
22482
- // Data & Ops
22482
+ // Data, Legal & Ops
22483
22483
  "data_analytics",
22484
+ "legal_compliance",
22484
22485
  "customer_success",
22485
22486
  "team_process",
22486
22487
  "program_mgmt",
22488
+ // Content & Portfolio
22489
+ "content",
22490
+ "education",
22487
22491
  "partnerships",
22492
+ "localisation",
22488
22493
  "portfolio"
22489
22494
  ];
22490
22495
  var UPG_STRUCTURE_PATTERNS = [