@unified-product-graph/mcp-server 0.6.3 → 0.7.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 +101 -96
- package/dist/index.js.map +1 -1
- package/dist/tools-manifest.json +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -160,7 +160,7 @@ var UPG_DOMAINS = [
|
|
|
160
160
|
"feature",
|
|
161
161
|
"feature_area",
|
|
162
162
|
"epic",
|
|
163
|
-
"
|
|
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
|
-
//
|
|
681
|
-
//
|
|
682
|
-
// `
|
|
683
|
-
//
|
|
684
|
-
//
|
|
685
|
-
//
|
|
686
|
-
//
|
|
687
|
-
//
|
|
688
|
-
//
|
|
689
|
-
//
|
|
690
|
-
//
|
|
691
|
-
|
|
692
|
-
{ name: "
|
|
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
|
|
1265
|
-
//
|
|
1266
|
-
//
|
|
1267
|
-
//
|
|
1268
|
-
//
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
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
|
-
// `
|
|
1290
|
-
// canonical `
|
|
1291
|
-
//
|
|
1292
|
-
//
|
|
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
|
-
|
|
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
|
|
3059
|
-
//
|
|
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: ["
|
|
3063
|
-
|
|
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
|
-
|
|
5713
|
-
// story_task lifecycle removed v0.4.0 collapsed
|
|
5714
|
-
//
|
|
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
|
-
//
|
|
5822
|
-
//
|
|
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
|
-
"
|
|
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
|
-
//
|
|
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
|
|
7551
|
-
}
|
|
7552
|
-
|
|
7553
|
-
|
|
7554
|
-
|
|
7555
|
-
|
|
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
|
-
//
|
|
10443
|
-
|
|
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": "
|
|
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": "
|
|
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
|
-
["
|
|
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", "
|
|
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
|
|
17152
|
-
entity_types: ["feature_area", "feature", "epic", "
|
|
17153
|
-
edge_chain: ["feature_area_contains_feature", "feature_decomposed_into_epic", "
|
|
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: "
|
|
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: "
|
|
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": "
|
|
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": "
|
|
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
|
-
"
|
|
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 = [
|
|
@@ -22496,7 +22501,7 @@ var UPG_STRUCTURE_PATTERNS = [
|
|
|
22496
22501
|
"quadrant",
|
|
22497
22502
|
"flow"
|
|
22498
22503
|
];
|
|
22499
|
-
var UPG_VERSION = "0.
|
|
22504
|
+
var UPG_VERSION = "0.7.0";
|
|
22500
22505
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
22501
22506
|
var UPG_TYPES = getTypes();
|
|
22502
22507
|
var UPG_TYPES_SET = new Set(UPG_TYPES);
|