@unified-product-graph/core 0.9.0 → 0.9.2
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 +39 -2
- package/dist/index.cjs +90 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +61 -17
- package/dist/index.d.ts +61 -17
- package/dist/index.js +90 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1442,10 +1442,10 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
1442
1442
|
source_type: string;
|
|
1443
1443
|
target_type: string;
|
|
1444
1444
|
};
|
|
1445
|
-
|
|
1445
|
+
journey_phase_spans_journey_step: {
|
|
1446
1446
|
forward_verb: string;
|
|
1447
1447
|
reverse_verb: string;
|
|
1448
|
-
classification: "
|
|
1448
|
+
classification: "cross-domain";
|
|
1449
1449
|
source_type: string;
|
|
1450
1450
|
target_type: string;
|
|
1451
1451
|
};
|
|
@@ -1456,6 +1456,20 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
1456
1456
|
source_type: string;
|
|
1457
1457
|
target_type: string;
|
|
1458
1458
|
};
|
|
1459
|
+
journey_action_surfaces_need: {
|
|
1460
|
+
forward_verb: string;
|
|
1461
|
+
reverse_verb: string;
|
|
1462
|
+
classification: "cross-domain";
|
|
1463
|
+
source_type: string;
|
|
1464
|
+
target_type: string;
|
|
1465
|
+
};
|
|
1466
|
+
journey_action_realised_by_feature: {
|
|
1467
|
+
forward_verb: string;
|
|
1468
|
+
reverse_verb: string;
|
|
1469
|
+
classification: "cross-domain";
|
|
1470
|
+
source_type: string;
|
|
1471
|
+
target_type: string;
|
|
1472
|
+
};
|
|
1459
1473
|
product_systematised_in_design_system: {
|
|
1460
1474
|
forward_verb: string;
|
|
1461
1475
|
reverse_verb: string;
|
|
@@ -6962,7 +6976,7 @@ interface UPGProduct {
|
|
|
6962
6976
|
/** Product lifecycle stages. Covers the full arc from napkin idea to end-of-life. */
|
|
6963
6977
|
type UPGProductStage = 'concept' | 'validation' | 'build' | 'beta' | 'launch' | 'growth' | 'mature' | 'maintenance' | 'sunset';
|
|
6964
6978
|
/** The set of valid cross-product relationship types */
|
|
6965
|
-
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts';
|
|
6979
|
+
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts' | 'contributes_to';
|
|
6966
6980
|
/**
|
|
6967
6981
|
* Runtime-checkable list of valid cross-product edge types. Mirrors
|
|
6968
6982
|
* `UPGCrossEdgeType` for use in validators and writers that need to test
|
|
@@ -7308,7 +7322,6 @@ interface EntityTypeMeta {
|
|
|
7308
7322
|
* creation. The score lives on the framework application (a `framework_exercise`
|
|
7309
7323
|
* includes-edge), never on the entity. Not field-absorption: this is a pointer,
|
|
7310
7324
|
* not embedded columns.
|
|
7311
|
-
* @see TPC-context/upg/08-decisions/2026-06-05-framework-scoped-scoring-completion.md
|
|
7312
7325
|
*/
|
|
7313
7326
|
default_frameworks?: string[];
|
|
7314
7327
|
}
|
|
@@ -10695,14 +10708,19 @@ interface UserJourneyProperties {
|
|
|
10695
10708
|
/** Scenario context */
|
|
10696
10709
|
scenario?: string;
|
|
10697
10710
|
}
|
|
10698
|
-
/** Phase within a user journey.
|
|
10711
|
+
/** Phase within a user journey. A temporal BAND over the journey's step
|
|
10712
|
+
* timeline, not a container that owns steps (UPG-663). A journey map renders
|
|
10713
|
+
* phases as a horizontal band above one timeline; a phase spans a range of
|
|
10714
|
+
* that timeline. Steps belong to the journey, not the phase.
|
|
10699
10715
|
*
|
|
10700
10716
|
* Per UPG principle P14, structural relationships are edges:
|
|
10701
|
-
* parent journey: `
|
|
10702
|
-
*
|
|
10703
|
-
*
|
|
10704
|
-
* `
|
|
10705
|
-
*
|
|
10717
|
+
* parent journey: `user_journey_passes_through_journey_phase`
|
|
10718
|
+
* (the journey carries the phase as a non-owning band overlay)
|
|
10719
|
+
* spanned steps: `journey_phase_spans_journey_step` (non-owning; the steps
|
|
10720
|
+
* are owned by `user_journey_contains_journey_step`, mirroring the
|
|
10721
|
+
* marketing precedent `customer_journey_stage_spans_journey_step`)
|
|
10722
|
+
* phase ordering: the `phase_order` scalar below (the convention shared
|
|
10723
|
+
* with `journey_step.step_order` and `journey_action.action_order`)
|
|
10706
10724
|
*
|
|
10707
10725
|
* @example
|
|
10708
10726
|
* const properties: JourneyPhaseProperties = {
|
|
@@ -10740,16 +10758,27 @@ interface JourneyPhaseProperties {
|
|
|
10740
10758
|
*/
|
|
10741
10759
|
timeframe?: string;
|
|
10742
10760
|
}
|
|
10743
|
-
/** Single step within a user journey.
|
|
10761
|
+
/** Single step within a user journey. A user-moment on the journey's single
|
|
10762
|
+
* step timeline. Steps belong to the journey via
|
|
10763
|
+
* `user_journey_contains_journey_step` (the stable 0.1.0 spine); a
|
|
10764
|
+
* `journey_phase` spans a range of them but does not own them (UPG-663).
|
|
10744
10765
|
*
|
|
10745
10766
|
* @example
|
|
10746
10767
|
* const properties: JourneyStepProperties = {
|
|
10768
|
+
* step_order: 1,
|
|
10747
10769
|
* touchpoint: 'in-product',
|
|
10748
10770
|
* channel: 'in-product',
|
|
10749
10771
|
* emotion_score: 4,
|
|
10750
10772
|
* }
|
|
10751
10773
|
*/
|
|
10752
10774
|
interface JourneyStepProperties {
|
|
10775
|
+
/**
|
|
10776
|
+
* Display order within the journey's step timeline (0-indexed). The scalar
|
|
10777
|
+
* ordering convention shared with `journey_phase.phase_order` and
|
|
10778
|
+
* `journey_action.action_order` (UPG-663). For branching journeys, the
|
|
10779
|
+
* explicit `journey_step_precedes_journey_step` edge captures the chain.
|
|
10780
|
+
*/
|
|
10781
|
+
step_order?: number;
|
|
10753
10782
|
/** Interaction touchpoint */
|
|
10754
10783
|
touchpoint?: string;
|
|
10755
10784
|
/** Channel (e.g. "web", "email", "in-store") */
|
|
@@ -10764,16 +10793,24 @@ interface JourneyStepProperties {
|
|
|
10764
10793
|
owner?: string;
|
|
10765
10794
|
}
|
|
10766
10795
|
/** Discrete action at a journey step, classified by service layer.
|
|
10796
|
+
* The finest blueprint layer (a service-blueprint row within a moment).
|
|
10767
10797
|
* Enables service blueprint rendering and cross-domain linking.
|
|
10768
10798
|
*
|
|
10769
10799
|
* Per UPG principle P14, structural relationships are edges:
|
|
10770
|
-
* parent step: `
|
|
10771
|
-
*
|
|
10772
|
-
*
|
|
10773
|
-
*
|
|
10800
|
+
* parent step: `journey_step_has_action` (the step owns its actions)
|
|
10801
|
+
* downstream need: `journey_action_surfaces_need`. Opportunity discovery
|
|
10802
|
+
* routes through `need`, which reaches `opportunity` via
|
|
10803
|
+
* `opportunity_addresses_need`; the `pain_score` / `opportunity_score`
|
|
10804
|
+
* scalars below are blueprint-cell diagnostics that fuel that discovery.
|
|
10805
|
+
* realising feature: `journey_action_realised_by_feature`
|
|
10806
|
+
*
|
|
10807
|
+
* The `system` property is a display label naming the performing system; when
|
|
10808
|
+
* a `service` entity exists, model the relationship structurally rather than
|
|
10809
|
+
* relying on the label.
|
|
10774
10810
|
*
|
|
10775
10811
|
* @example
|
|
10776
10812
|
* const properties: JourneyActionProperties = {
|
|
10813
|
+
* action_order: 0,
|
|
10777
10814
|
* layer: 'user',
|
|
10778
10815
|
* action_description: 'User pastes a meeting transcript into the empty canvas',
|
|
10779
10816
|
* channel: 'in-app',
|
|
@@ -10785,6 +10822,13 @@ interface JourneyStepProperties {
|
|
|
10785
10822
|
* }
|
|
10786
10823
|
*/
|
|
10787
10824
|
interface JourneyActionProperties {
|
|
10825
|
+
/**
|
|
10826
|
+
* Display order of this action within its step (0-indexed). The scalar
|
|
10827
|
+
* ordering convention shared with `journey_phase.phase_order` and
|
|
10828
|
+
* `journey_step.step_order` (UPG-663). Orders the service-blueprint rows
|
|
10829
|
+
* within a single moment.
|
|
10830
|
+
*/
|
|
10831
|
+
action_order?: number;
|
|
10788
10832
|
/** Service layer */
|
|
10789
10833
|
layer: 'user' | 'frontstage' | 'backstage' | 'support';
|
|
10790
10834
|
/** Plain-language description. Primary content of the action. */
|
|
@@ -18006,7 +18050,7 @@ type UPGNode<T extends keyof UPGPropertyMap = keyof UPGPropertyMap> = UPGBaseNod
|
|
|
18006
18050
|
* AUTO-GENERATED by scripts/generate-property-registry.ts
|
|
18007
18051
|
* Do not edit manually. Run: npx tsx scripts/generate-property-registry.ts
|
|
18008
18052
|
*
|
|
18009
|
-
* Generated: 2026-06-
|
|
18053
|
+
* Generated: 2026-06-09T16:53:52.006Z
|
|
18010
18054
|
* Entity types with properties: 316
|
|
18011
18055
|
*/
|
|
18012
18056
|
interface PropertyDefinition {
|
|
@@ -20447,7 +20491,7 @@ declare function isCanonical(text: string): boolean;
|
|
|
20447
20491
|
* it stamps the `upg_version` field of every `.upg` file written by the SDK.
|
|
20448
20492
|
* The `check:version-lockstep` gate enforces this at release time.
|
|
20449
20493
|
*/
|
|
20450
|
-
declare const UPG_VERSION: "0.9.
|
|
20494
|
+
declare const UPG_VERSION: "0.9.2";
|
|
20451
20495
|
/**
|
|
20452
20496
|
* The `.upg` JSON document format version. Written to the `upg_version` field.
|
|
20453
20497
|
* Evolves independently from `UPG_VERSION` (the catalogue version).
|
package/dist/index.d.ts
CHANGED
|
@@ -1442,10 +1442,10 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
1442
1442
|
source_type: string;
|
|
1443
1443
|
target_type: string;
|
|
1444
1444
|
};
|
|
1445
|
-
|
|
1445
|
+
journey_phase_spans_journey_step: {
|
|
1446
1446
|
forward_verb: string;
|
|
1447
1447
|
reverse_verb: string;
|
|
1448
|
-
classification: "
|
|
1448
|
+
classification: "cross-domain";
|
|
1449
1449
|
source_type: string;
|
|
1450
1450
|
target_type: string;
|
|
1451
1451
|
};
|
|
@@ -1456,6 +1456,20 @@ declare const UPG_EDGE_CATALOG: {
|
|
|
1456
1456
|
source_type: string;
|
|
1457
1457
|
target_type: string;
|
|
1458
1458
|
};
|
|
1459
|
+
journey_action_surfaces_need: {
|
|
1460
|
+
forward_verb: string;
|
|
1461
|
+
reverse_verb: string;
|
|
1462
|
+
classification: "cross-domain";
|
|
1463
|
+
source_type: string;
|
|
1464
|
+
target_type: string;
|
|
1465
|
+
};
|
|
1466
|
+
journey_action_realised_by_feature: {
|
|
1467
|
+
forward_verb: string;
|
|
1468
|
+
reverse_verb: string;
|
|
1469
|
+
classification: "cross-domain";
|
|
1470
|
+
source_type: string;
|
|
1471
|
+
target_type: string;
|
|
1472
|
+
};
|
|
1459
1473
|
product_systematised_in_design_system: {
|
|
1460
1474
|
forward_verb: string;
|
|
1461
1475
|
reverse_verb: string;
|
|
@@ -6962,7 +6976,7 @@ interface UPGProduct {
|
|
|
6962
6976
|
/** Product lifecycle stages. Covers the full arc from napkin idea to end-of-life. */
|
|
6963
6977
|
type UPGProductStage = 'concept' | 'validation' | 'build' | 'beta' | 'launch' | 'growth' | 'mature' | 'maintenance' | 'sunset';
|
|
6964
6978
|
/** The set of valid cross-product relationship types */
|
|
6965
|
-
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts';
|
|
6979
|
+
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts' | 'contributes_to';
|
|
6966
6980
|
/**
|
|
6967
6981
|
* Runtime-checkable list of valid cross-product edge types. Mirrors
|
|
6968
6982
|
* `UPGCrossEdgeType` for use in validators and writers that need to test
|
|
@@ -7308,7 +7322,6 @@ interface EntityTypeMeta {
|
|
|
7308
7322
|
* creation. The score lives on the framework application (a `framework_exercise`
|
|
7309
7323
|
* includes-edge), never on the entity. Not field-absorption: this is a pointer,
|
|
7310
7324
|
* not embedded columns.
|
|
7311
|
-
* @see TPC-context/upg/08-decisions/2026-06-05-framework-scoped-scoring-completion.md
|
|
7312
7325
|
*/
|
|
7313
7326
|
default_frameworks?: string[];
|
|
7314
7327
|
}
|
|
@@ -10695,14 +10708,19 @@ interface UserJourneyProperties {
|
|
|
10695
10708
|
/** Scenario context */
|
|
10696
10709
|
scenario?: string;
|
|
10697
10710
|
}
|
|
10698
|
-
/** Phase within a user journey.
|
|
10711
|
+
/** Phase within a user journey. A temporal BAND over the journey's step
|
|
10712
|
+
* timeline, not a container that owns steps (UPG-663). A journey map renders
|
|
10713
|
+
* phases as a horizontal band above one timeline; a phase spans a range of
|
|
10714
|
+
* that timeline. Steps belong to the journey, not the phase.
|
|
10699
10715
|
*
|
|
10700
10716
|
* Per UPG principle P14, structural relationships are edges:
|
|
10701
|
-
* parent journey: `
|
|
10702
|
-
*
|
|
10703
|
-
*
|
|
10704
|
-
* `
|
|
10705
|
-
*
|
|
10717
|
+
* parent journey: `user_journey_passes_through_journey_phase`
|
|
10718
|
+
* (the journey carries the phase as a non-owning band overlay)
|
|
10719
|
+
* spanned steps: `journey_phase_spans_journey_step` (non-owning; the steps
|
|
10720
|
+
* are owned by `user_journey_contains_journey_step`, mirroring the
|
|
10721
|
+
* marketing precedent `customer_journey_stage_spans_journey_step`)
|
|
10722
|
+
* phase ordering: the `phase_order` scalar below (the convention shared
|
|
10723
|
+
* with `journey_step.step_order` and `journey_action.action_order`)
|
|
10706
10724
|
*
|
|
10707
10725
|
* @example
|
|
10708
10726
|
* const properties: JourneyPhaseProperties = {
|
|
@@ -10740,16 +10758,27 @@ interface JourneyPhaseProperties {
|
|
|
10740
10758
|
*/
|
|
10741
10759
|
timeframe?: string;
|
|
10742
10760
|
}
|
|
10743
|
-
/** Single step within a user journey.
|
|
10761
|
+
/** Single step within a user journey. A user-moment on the journey's single
|
|
10762
|
+
* step timeline. Steps belong to the journey via
|
|
10763
|
+
* `user_journey_contains_journey_step` (the stable 0.1.0 spine); a
|
|
10764
|
+
* `journey_phase` spans a range of them but does not own them (UPG-663).
|
|
10744
10765
|
*
|
|
10745
10766
|
* @example
|
|
10746
10767
|
* const properties: JourneyStepProperties = {
|
|
10768
|
+
* step_order: 1,
|
|
10747
10769
|
* touchpoint: 'in-product',
|
|
10748
10770
|
* channel: 'in-product',
|
|
10749
10771
|
* emotion_score: 4,
|
|
10750
10772
|
* }
|
|
10751
10773
|
*/
|
|
10752
10774
|
interface JourneyStepProperties {
|
|
10775
|
+
/**
|
|
10776
|
+
* Display order within the journey's step timeline (0-indexed). The scalar
|
|
10777
|
+
* ordering convention shared with `journey_phase.phase_order` and
|
|
10778
|
+
* `journey_action.action_order` (UPG-663). For branching journeys, the
|
|
10779
|
+
* explicit `journey_step_precedes_journey_step` edge captures the chain.
|
|
10780
|
+
*/
|
|
10781
|
+
step_order?: number;
|
|
10753
10782
|
/** Interaction touchpoint */
|
|
10754
10783
|
touchpoint?: string;
|
|
10755
10784
|
/** Channel (e.g. "web", "email", "in-store") */
|
|
@@ -10764,16 +10793,24 @@ interface JourneyStepProperties {
|
|
|
10764
10793
|
owner?: string;
|
|
10765
10794
|
}
|
|
10766
10795
|
/** Discrete action at a journey step, classified by service layer.
|
|
10796
|
+
* The finest blueprint layer (a service-blueprint row within a moment).
|
|
10767
10797
|
* Enables service blueprint rendering and cross-domain linking.
|
|
10768
10798
|
*
|
|
10769
10799
|
* Per UPG principle P14, structural relationships are edges:
|
|
10770
|
-
* parent step: `
|
|
10771
|
-
*
|
|
10772
|
-
*
|
|
10773
|
-
*
|
|
10800
|
+
* parent step: `journey_step_has_action` (the step owns its actions)
|
|
10801
|
+
* downstream need: `journey_action_surfaces_need`. Opportunity discovery
|
|
10802
|
+
* routes through `need`, which reaches `opportunity` via
|
|
10803
|
+
* `opportunity_addresses_need`; the `pain_score` / `opportunity_score`
|
|
10804
|
+
* scalars below are blueprint-cell diagnostics that fuel that discovery.
|
|
10805
|
+
* realising feature: `journey_action_realised_by_feature`
|
|
10806
|
+
*
|
|
10807
|
+
* The `system` property is a display label naming the performing system; when
|
|
10808
|
+
* a `service` entity exists, model the relationship structurally rather than
|
|
10809
|
+
* relying on the label.
|
|
10774
10810
|
*
|
|
10775
10811
|
* @example
|
|
10776
10812
|
* const properties: JourneyActionProperties = {
|
|
10813
|
+
* action_order: 0,
|
|
10777
10814
|
* layer: 'user',
|
|
10778
10815
|
* action_description: 'User pastes a meeting transcript into the empty canvas',
|
|
10779
10816
|
* channel: 'in-app',
|
|
@@ -10785,6 +10822,13 @@ interface JourneyStepProperties {
|
|
|
10785
10822
|
* }
|
|
10786
10823
|
*/
|
|
10787
10824
|
interface JourneyActionProperties {
|
|
10825
|
+
/**
|
|
10826
|
+
* Display order of this action within its step (0-indexed). The scalar
|
|
10827
|
+
* ordering convention shared with `journey_phase.phase_order` and
|
|
10828
|
+
* `journey_step.step_order` (UPG-663). Orders the service-blueprint rows
|
|
10829
|
+
* within a single moment.
|
|
10830
|
+
*/
|
|
10831
|
+
action_order?: number;
|
|
10788
10832
|
/** Service layer */
|
|
10789
10833
|
layer: 'user' | 'frontstage' | 'backstage' | 'support';
|
|
10790
10834
|
/** Plain-language description. Primary content of the action. */
|
|
@@ -18006,7 +18050,7 @@ type UPGNode<T extends keyof UPGPropertyMap = keyof UPGPropertyMap> = UPGBaseNod
|
|
|
18006
18050
|
* AUTO-GENERATED by scripts/generate-property-registry.ts
|
|
18007
18051
|
* Do not edit manually. Run: npx tsx scripts/generate-property-registry.ts
|
|
18008
18052
|
*
|
|
18009
|
-
* Generated: 2026-06-
|
|
18053
|
+
* Generated: 2026-06-09T16:53:52.006Z
|
|
18010
18054
|
* Entity types with properties: 316
|
|
18011
18055
|
*/
|
|
18012
18056
|
interface PropertyDefinition {
|
|
@@ -20447,7 +20491,7 @@ declare function isCanonical(text: string): boolean;
|
|
|
20447
20491
|
* it stamps the `upg_version` field of every `.upg` file written by the SDK.
|
|
20448
20492
|
* The `check:version-lockstep` gate enforces this at release time.
|
|
20449
20493
|
*/
|
|
20450
|
-
declare const UPG_VERSION: "0.9.
|
|
20494
|
+
declare const UPG_VERSION: "0.9.2";
|
|
20451
20495
|
/**
|
|
20452
20496
|
* The `.upg` JSON document format version. Written to the `upg_version` field.
|
|
20453
20497
|
* Evolves independently from `UPG_VERSION` (the catalogue version).
|
package/dist/index.js
CHANGED
|
@@ -1292,8 +1292,24 @@ var UPG_EDGE_CATALOG = {
|
|
|
1292
1292
|
journey_step_realised_by_feature: { forward_verb: "realised_by", reverse_verb: "realises", classification: "cross-domain", source_type: "journey_step", target_type: "feature" },
|
|
1293
1293
|
opportunity_improves_user_journey: { forward_verb: "improves", reverse_verb: "improved_by", classification: "cross-domain", source_type: "opportunity", target_type: "user_journey" },
|
|
1294
1294
|
user_journey_passes_through_journey_phase: { forward_verb: "passes_through", reverse_verb: "is_phase_of", classification: "hierarchy", source_type: "user_journey", target_type: "journey_phase" },
|
|
1295
|
-
|
|
1295
|
+
// (since v0.9.2, UPG-663) A journey_phase is a temporal BAND over the
|
|
1296
|
+
// journey's single step timeline, not a container that owns steps. Steps
|
|
1297
|
+
// belong to the journey via `user_journey_contains_journey_step` (the stable
|
|
1298
|
+
// 0.1.0 spine); a phase merely SPANS a range of them. Mirrors the marketing
|
|
1299
|
+
// precedent `customer_journey_stage_spans_journey_step`. Renamed from the
|
|
1300
|
+
// owning `journey_phase_has_step` (hierarchy) so a step has exactly one
|
|
1301
|
+
// containment parent. See UPG_EDGE_MIGRATIONS['0.9.2'].
|
|
1302
|
+
journey_phase_spans_journey_step: { forward_verb: "spans", reverse_verb: "spanned_by", classification: "cross-domain", source_type: "journey_phase", target_type: "journey_step" },
|
|
1296
1303
|
journey_step_has_action: { forward_verb: "has_action", reverse_verb: "is_action_in", classification: "hierarchy", source_type: "journey_step", target_type: "journey_action" },
|
|
1304
|
+
// (since v0.9.2, UPG-663) journey_action outbound edges. Fixes the
|
|
1305
|
+
// discovery dead-end (D2). The finest blueprint layer carries pain_score /
|
|
1306
|
+
// opportunity_score "to drive opportunity discovery" but previously had zero
|
|
1307
|
+
// outbound edges. Opportunity discovery routes through `need` (mirroring
|
|
1308
|
+
// `journey_step_reveals_need`), which already reaches `opportunity` via the
|
|
1309
|
+
// user chain; the action does not link an opportunity directly. The feature
|
|
1310
|
+
// edge mirrors `journey_step_realised_by_feature` one level deeper.
|
|
1311
|
+
journey_action_surfaces_need: { forward_verb: "surfaces", reverse_verb: "surfaced_in", classification: "cross-domain", source_type: "journey_action", target_type: "need" },
|
|
1312
|
+
journey_action_realised_by_feature: { forward_verb: "realised_by", reverse_verb: "realises", classification: "cross-domain", source_type: "journey_action", target_type: "feature" },
|
|
1297
1313
|
// 2.5 UI System Domain
|
|
1298
1314
|
product_systematised_in_design_system: { forward_verb: "systematised_in", reverse_verb: "systematises", classification: "hierarchy", source_type: "product", target_type: "design_system" },
|
|
1299
1315
|
product_built_with_design_component: { forward_verb: "built_with", reverse_verb: "built_for", classification: "hierarchy", source_type: "product", target_type: "design_component" },
|
|
@@ -2759,7 +2775,8 @@ var UPG_CROSS_EDGE_TYPES = [
|
|
|
2759
2775
|
"depends_on_product",
|
|
2760
2776
|
"cannibalises",
|
|
2761
2777
|
"succeeds",
|
|
2762
|
-
"hosts"
|
|
2778
|
+
"hosts",
|
|
2779
|
+
"contributes_to"
|
|
2763
2780
|
];
|
|
2764
2781
|
|
|
2765
2782
|
// src/registry/entity-type-resolution.ts
|
|
@@ -3050,8 +3067,13 @@ var UPG_VALID_CHILDREN = {
|
|
|
3050
3067
|
// parallel to `observation: ['quote']`. Research-synthesis canon.
|
|
3051
3068
|
// Pairs with `insight_evidenced_by_quote` in the edge catalog.
|
|
3052
3069
|
// ── Design hierarchy ────────────────────────────────────────────────────────
|
|
3070
|
+
// (UPG-663, v0.9.2) A user_journey owns its steps (the stable 0.1.0 spine)
|
|
3071
|
+
// and carries phases as a non-owning band overlay. A journey_phase is NO
|
|
3072
|
+
// LONGER a containment parent of journey_step: it SPANS steps via the
|
|
3073
|
+
// `journey_phase_spans_journey_step` edge (mirroring the marketing
|
|
3074
|
+
// `customer_journey_stage_spans_journey_step` precedent), so each step has
|
|
3075
|
+
// exactly one containment parent and the journey has one canonical step list.
|
|
3053
3076
|
user_journey: ["journey_step", "journey_phase"],
|
|
3054
|
-
journey_phase: ["journey_step"],
|
|
3055
3077
|
journey_step: ["journey_action"],
|
|
3056
3078
|
// v0.5.8 (UPG-528 Part 2d): insights own their evidencing quotes;
|
|
3057
3079
|
// parallel to `observation: ['quote']`. Research-synthesis canon
|
|
@@ -7604,6 +7626,20 @@ function getSplitMigrations(fromVersion, toVersion) {
|
|
|
7604
7626
|
return result;
|
|
7605
7627
|
}
|
|
7606
7628
|
var UPG_EDGE_MIGRATIONS = {
|
|
7629
|
+
"0.9.2": [
|
|
7630
|
+
// (since v0.9.2, UPG-663) Journey-model disambiguation. A journey_phase
|
|
7631
|
+
// is a temporal BAND over the journey's single step timeline, not a
|
|
7632
|
+
// container that owns steps. The owning hierarchy edge
|
|
7633
|
+
// `journey_phase_has_step` is renamed to the non-owning
|
|
7634
|
+
// `journey_phase_spans_journey_step` (mirroring the marketing precedent
|
|
7635
|
+
// `customer_journey_stage_spans_journey_step`). Steps stay owned by the
|
|
7636
|
+
// journey via `user_journey_contains_journey_step` (the stable 0.1.0
|
|
7637
|
+
// spine), so each step keeps a single containment parent and the journey
|
|
7638
|
+
// renders one canonical step list. Endpoints are unchanged
|
|
7639
|
+
// (journey_phase → journey_step); only the edge key and its grammar
|
|
7640
|
+
// (verb has_step → spans, classification hierarchy → cross-domain) change.
|
|
7641
|
+
{ kind: "rename", from: "journey_phase_has_step", to: "journey_phase_spans_journey_step", requires_source_type: "journey_phase", requires_target_type: "journey_step", reason: "Journey-model disambiguation (UPG-663): a phase spans steps, it does not own them. The phase to step edge becomes non-owning (verb has_step to spans), so the step keeps a single containment parent (the journey) and the journey has one canonical step list." }
|
|
7642
|
+
],
|
|
7607
7643
|
"0.9.0": [
|
|
7608
7644
|
// (since v0.9.0, UPG-660) theme → roadmap_theme. The four canonical edges that
|
|
7609
7645
|
// touch the roadmap theme are renamed to the roadmap_theme form. Endpoint guards
|
|
@@ -10102,6 +10138,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10102
10138
|
},
|
|
10103
10139
|
// JourneyActionProperties: Discrete action at a journey step, classified by service layer.
|
|
10104
10140
|
journey_action: {
|
|
10141
|
+
action_order: { type: "number", description: "Display order of this action within its step (0-indexed). The scalar ordering convention shared with `journey_phase.phase_order` and `journey_step.step_order` (UPG-663). Orders the service-blueprint rows within a single moment." },
|
|
10105
10142
|
layer: { type: "string", enum: ["user", "frontstage", "backstage", "support"], description: "Service layer" },
|
|
10106
10143
|
action_description: { type: "string", description: "Plain-language description. Primary content of the action." },
|
|
10107
10144
|
channel: { type: "string", enum: ["in-app", "email", "web", "mobile", "phone", "in-person", "sms", "social", "other"], description: "Channel or surface. Keeps service-blueprint columns consistent across the journey." },
|
|
@@ -10133,7 +10170,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10133
10170
|
system: { type: "string", description: "Performing system or service" },
|
|
10134
10171
|
notes: { type: "string", description: "Free-text notes, observations, or follow-up questions" }
|
|
10135
10172
|
},
|
|
10136
|
-
// JourneyPhaseProperties: Phase within a user journey.
|
|
10173
|
+
// JourneyPhaseProperties: Phase within a user journey. A temporal BAND over the journey's step
|
|
10137
10174
|
journey_phase: {
|
|
10138
10175
|
phase_order: { type: "number", description: "Display order within the journey (0-indexed)" },
|
|
10139
10176
|
label: { type: "string", description: 'Short human-readable name. @example "Discovery", "Onboarding", "Activation"' },
|
|
@@ -10144,8 +10181,9 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10144
10181
|
key_questions: { type: "string[]", description: "Open questions the user asks themselves. Fuel for design and content priorities." },
|
|
10145
10182
|
timeframe: { type: "string", description: 'Typical time window. @example "first 30 seconds", "days 1\u20137", "onboarding week"' }
|
|
10146
10183
|
},
|
|
10147
|
-
// JourneyStepProperties: Single step within a user journey.
|
|
10184
|
+
// JourneyStepProperties: Single step within a user journey. A user-moment on the journey's single
|
|
10148
10185
|
journey_step: {
|
|
10186
|
+
step_order: { type: "number", description: "Display order within the journey's step timeline (0-indexed). The scalar ordering convention shared with `journey_phase.phase_order` and `journey_action.action_order` (UPG-663). For branching journeys, the explicit `journey_step_precedes_journey_step` edge captures the chain." },
|
|
10149
10187
|
touchpoint: { type: "string", description: "Interaction touchpoint" },
|
|
10150
10188
|
channel: { type: "string", description: 'Channel (e.g. "web", "email", "in-store")' },
|
|
10151
10189
|
emotion_score: {
|
|
@@ -18068,8 +18106,13 @@ var STANDARD_LABELS = {
|
|
|
18068
18106
|
interview_guide: { alt_labels: ["discussion guide", "interview script", "moderator guide"] },
|
|
18069
18107
|
survey_response: { alt_labels: ["survey answer", "questionnaire response"] },
|
|
18070
18108
|
// Design layer
|
|
18071
|
-
|
|
18072
|
-
|
|
18109
|
+
// (UPG-663) alt_labels must not collide with other entity types' canonical
|
|
18110
|
+
// names or alt_labels, or the string->type resolver is ambiguous.
|
|
18111
|
+
// Dropped 'customer journey' (collides with customer_journey_stage),
|
|
18112
|
+
// 'touchpoint' and 'journey phase' (both distinct entity surfaces: a
|
|
18113
|
+
// touchpoint is the journey_step.touchpoint property, a phase is journey_phase).
|
|
18114
|
+
user_journey: { alt_labels: ["journey map", "experience map", "journey"] },
|
|
18115
|
+
journey_step: { alt_labels: ["journey moment", "journey stage"] },
|
|
18073
18116
|
design_component: { alt_labels: ["component", "ui component", "design element"] },
|
|
18074
18117
|
design_token: { alt_labels: ["token", "style token", "css variable"] },
|
|
18075
18118
|
wireframe: { alt_labels: ["wireflow", "lo-fi mockup", "skeleton"] },
|
|
@@ -20134,7 +20177,11 @@ var PRODUCT_SPEC_GUIDE = {
|
|
|
20134
20177
|
var UX_DESIGN_GUIDE = {
|
|
20135
20178
|
domain_id: "ux_design",
|
|
20136
20179
|
anchor_entity: "user_journey",
|
|
20137
|
-
|
|
20180
|
+
// (UPG-663) creation order follows containment: a journey_action is a child
|
|
20181
|
+
// of a journey_step, so the step must precede the action. The journey is the
|
|
20182
|
+
// anchor; phases are the band overlay; steps are the timeline; actions
|
|
20183
|
+
// decompose a step into service-blueprint rows.
|
|
20184
|
+
creation_sequence: ["user_journey", "journey_phase", "journey_step", "journey_action", "screen", "screen_state", "user_flow", "wireframe", "prototype", "design_question", "design_concept"],
|
|
20138
20185
|
patterns: [
|
|
20139
20186
|
{
|
|
20140
20187
|
name: "Journey to Screen Flow",
|
|
@@ -23431,6 +23478,40 @@ var UPG_ANTI_PATTERNS = [
|
|
|
23431
23478
|
stages: ["concept", "validation", "build", "beta", "launch", "growth", "mature"],
|
|
23432
23479
|
severity: "medium",
|
|
23433
23480
|
source: { kind: "fundamental" }
|
|
23481
|
+
},
|
|
23482
|
+
// ── Experience-design layer ─────────────────────────────────────────────
|
|
23483
|
+
{
|
|
23484
|
+
id: "journey-phases-without-canonical-steps",
|
|
23485
|
+
name: "Journey phases without a step spine",
|
|
23486
|
+
description: 'The graph has journey phases spanning steps (`journey_phase_spans_journey_step`), but no journey owns its steps via `user_journey_contains_journey_step`. A phase is a band over a step timeline, not a container. When the timeline itself is missing there is no canonical answer to "what are the steps of this journey?". The phase overlay points at steps the journey does not own.',
|
|
23487
|
+
structured_condition: {
|
|
23488
|
+
operator: "and",
|
|
23489
|
+
checks: [
|
|
23490
|
+
{
|
|
23491
|
+
check: {
|
|
23492
|
+
type: "relationship",
|
|
23493
|
+
source_type: "journey_phase",
|
|
23494
|
+
edge_type: "journey_phase_spans_journey_step",
|
|
23495
|
+
target_type: "journey_step",
|
|
23496
|
+
comparison: "exists"
|
|
23497
|
+
}
|
|
23498
|
+
},
|
|
23499
|
+
{
|
|
23500
|
+
check: {
|
|
23501
|
+
type: "relationship",
|
|
23502
|
+
source_type: "user_journey",
|
|
23503
|
+
edge_type: "user_journey_contains_journey_step",
|
|
23504
|
+
target_type: "journey_step",
|
|
23505
|
+
comparison: "not_exists"
|
|
23506
|
+
}
|
|
23507
|
+
}
|
|
23508
|
+
]
|
|
23509
|
+
},
|
|
23510
|
+
why_it_matters: "Steps owned by no journey render a different step list per consumer: the phase overlay sees them, a journey-direct walk does not. The journey has no deterministic step spine to traverse, score, or map to screens.",
|
|
23511
|
+
remediation: "Own every step under its journey with `user_journey_contains_journey_step`, then let phases span ranges of that single timeline via `journey_phase_spans_journey_step`. The phase is a non-owning band overlay, not the step container.",
|
|
23512
|
+
stages: ["concept", "validation", "build", "beta", "launch", "growth"],
|
|
23513
|
+
severity: "high",
|
|
23514
|
+
source: { kind: "fundamental" }
|
|
23434
23515
|
}
|
|
23435
23516
|
];
|
|
23436
23517
|
function getAntiPatternById(id) {
|
|
@@ -25953,7 +26034,7 @@ function isCanonical(text) {
|
|
|
25953
26034
|
}
|
|
25954
26035
|
|
|
25955
26036
|
// src/index.ts
|
|
25956
|
-
var UPG_VERSION = "0.9.
|
|
26037
|
+
var UPG_VERSION = "0.9.2";
|
|
25957
26038
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
25958
26039
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
25959
26040
|
var UPG_TYPES = getTypes();
|