@unified-product-graph/core 0.10.1 → 0.10.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/dist/index.cjs +55 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -2
- package/dist/index.d.ts +27 -2
- package/dist/index.js +55 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -7208,7 +7208,7 @@ interface UPGProduct {
|
|
|
7208
7208
|
/** Product lifecycle stages. Covers the full arc from napkin idea to end-of-life. */
|
|
7209
7209
|
type UPGProductStage = 'concept' | 'validation' | 'build' | 'beta' | 'launch' | 'growth' | 'mature' | 'maintenance' | 'sunset';
|
|
7210
7210
|
/** The set of valid cross-product relationship types */
|
|
7211
|
-
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts' | 'contributes_to' | 'instance_of' | 'area_serves_persona' | 'area_targets_market_segment' | 'rolls_up_to' | 'product_implements_specification' | 'product_exposes_specification' | 'feature_conforms_to_specification' | 'api_contract_speaks_specification' | 'product_exposes_primitive' | 'feature_manipulates_primitive' | 'primitive_stored_as_data_type' | 'feature_rivals_competitor_feature' | 'competitor_signal_maps_to_feature' | 'competitor_signal_surfaces_opportunity';
|
|
7211
|
+
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts' | 'contributes_to' | 'instance_of' | 'area_serves_persona' | 'area_targets_market_segment' | 'rolls_up_to' | 'product_implements_specification' | 'product_exposes_specification' | 'feature_conforms_to_specification' | 'api_contract_speaks_specification' | 'product_exposes_primitive' | 'feature_manipulates_primitive' | 'primitive_stored_as_data_type' | 'feature_rivals_competitor_feature' | 'competitor_signal_maps_to_feature' | 'competitor_signal_surfaces_opportunity' | 'competitor_classified_as_classification_value';
|
|
7212
7212
|
/**
|
|
7213
7213
|
* Runtime-checkable list of valid cross-product edge types. Mirrors
|
|
7214
7214
|
* `UPGCrossEdgeType` for use in validators and writers that need to test
|
|
@@ -8657,6 +8657,25 @@ type UPGPropertyMigration = {
|
|
|
8657
8657
|
reset_value?: string;
|
|
8658
8658
|
/** Human-readable explanation surfaced in load-time warnings. */
|
|
8659
8659
|
reason: string;
|
|
8660
|
+
} | {
|
|
8661
|
+
/**
|
|
8662
|
+
* Reshape a bare numeric property into a `UPGAssessment` object
|
|
8663
|
+
* (`{ value, label, scale_id }`). For the v0.10.0 property-registry
|
|
8664
|
+
* correction (#43): interfaces that always declared `UPGAssessment` were
|
|
8665
|
+
* generated loosely, so pre-0.10.0 graphs stored a bare number (e.g.
|
|
8666
|
+
* `market_trend.impact: 4`). This wraps that number on its canonical scale,
|
|
8667
|
+
* deriving the qualitative `label` from the scale's points. Idempotent: a
|
|
8668
|
+
* value that is already an object (assessment) passes through untouched.
|
|
8669
|
+
*/
|
|
8670
|
+
kind: 'reshape_value_to_assessment';
|
|
8671
|
+
/** The entity type this rule applies to (or `'*'` for all types). */
|
|
8672
|
+
type: string;
|
|
8673
|
+
/** Key inside `properties` whose bare number is wrapped (stays in the bag). */
|
|
8674
|
+
property: string;
|
|
8675
|
+
/** The assessment scale to label the value on (e.g. `impact_5`, `importance_5`). */
|
|
8676
|
+
scale_id: string;
|
|
8677
|
+
/** Human-readable explanation surfaced in load-time warnings. */
|
|
8678
|
+
reason: string;
|
|
8660
8679
|
};
|
|
8661
8680
|
/**
|
|
8662
8681
|
* Version-scoped property migrations. Same convention as `UPG_MIGRATIONS`:
|
|
@@ -8688,6 +8707,12 @@ type UPGPropertyMigrationChange = {
|
|
|
8688
8707
|
property: string;
|
|
8689
8708
|
to_property?: string;
|
|
8690
8709
|
value_changed: boolean;
|
|
8710
|
+
} | {
|
|
8711
|
+
kind: 'reshaped_to_assessment';
|
|
8712
|
+
property: string;
|
|
8713
|
+
scale_id: string;
|
|
8714
|
+
value: number;
|
|
8715
|
+
label: string;
|
|
8691
8716
|
};
|
|
8692
8717
|
/**
|
|
8693
8718
|
* Apply property migrations to a single node. Returns the (possibly new) node
|
|
@@ -21413,7 +21438,7 @@ declare function isCanonical(text: string): boolean;
|
|
|
21413
21438
|
* it stamps the `upg_version` field of every `.upg` file written by the SDK.
|
|
21414
21439
|
* The `check:version-lockstep` gate enforces this at release time.
|
|
21415
21440
|
*/
|
|
21416
|
-
declare const UPG_VERSION: "0.10.
|
|
21441
|
+
declare const UPG_VERSION: "0.10.2";
|
|
21417
21442
|
/**
|
|
21418
21443
|
* The `.upg` JSON document format version. Written to the `upg_version` field.
|
|
21419
21444
|
* Evolves independently from `UPG_VERSION` (the catalogue version).
|
package/dist/index.d.ts
CHANGED
|
@@ -7208,7 +7208,7 @@ interface UPGProduct {
|
|
|
7208
7208
|
/** Product lifecycle stages. Covers the full arc from napkin idea to end-of-life. */
|
|
7209
7209
|
type UPGProductStage = 'concept' | 'validation' | 'build' | 'beta' | 'launch' | 'growth' | 'mature' | 'maintenance' | 'sunset';
|
|
7210
7210
|
/** The set of valid cross-product relationship types */
|
|
7211
|
-
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts' | 'contributes_to' | 'instance_of' | 'area_serves_persona' | 'area_targets_market_segment' | 'rolls_up_to' | 'product_implements_specification' | 'product_exposes_specification' | 'feature_conforms_to_specification' | 'api_contract_speaks_specification' | 'product_exposes_primitive' | 'feature_manipulates_primitive' | 'primitive_stored_as_data_type' | 'feature_rivals_competitor_feature' | 'competitor_signal_maps_to_feature' | 'competitor_signal_surfaces_opportunity';
|
|
7211
|
+
type UPGCrossEdgeType = 'shares_persona' | 'shares_competitor' | 'shares_metric' | 'depends_on_product' | 'cannibalises' | 'succeeds' | 'hosts' | 'contributes_to' | 'instance_of' | 'area_serves_persona' | 'area_targets_market_segment' | 'rolls_up_to' | 'product_implements_specification' | 'product_exposes_specification' | 'feature_conforms_to_specification' | 'api_contract_speaks_specification' | 'product_exposes_primitive' | 'feature_manipulates_primitive' | 'primitive_stored_as_data_type' | 'feature_rivals_competitor_feature' | 'competitor_signal_maps_to_feature' | 'competitor_signal_surfaces_opportunity' | 'competitor_classified_as_classification_value';
|
|
7212
7212
|
/**
|
|
7213
7213
|
* Runtime-checkable list of valid cross-product edge types. Mirrors
|
|
7214
7214
|
* `UPGCrossEdgeType` for use in validators and writers that need to test
|
|
@@ -8657,6 +8657,25 @@ type UPGPropertyMigration = {
|
|
|
8657
8657
|
reset_value?: string;
|
|
8658
8658
|
/** Human-readable explanation surfaced in load-time warnings. */
|
|
8659
8659
|
reason: string;
|
|
8660
|
+
} | {
|
|
8661
|
+
/**
|
|
8662
|
+
* Reshape a bare numeric property into a `UPGAssessment` object
|
|
8663
|
+
* (`{ value, label, scale_id }`). For the v0.10.0 property-registry
|
|
8664
|
+
* correction (#43): interfaces that always declared `UPGAssessment` were
|
|
8665
|
+
* generated loosely, so pre-0.10.0 graphs stored a bare number (e.g.
|
|
8666
|
+
* `market_trend.impact: 4`). This wraps that number on its canonical scale,
|
|
8667
|
+
* deriving the qualitative `label` from the scale's points. Idempotent: a
|
|
8668
|
+
* value that is already an object (assessment) passes through untouched.
|
|
8669
|
+
*/
|
|
8670
|
+
kind: 'reshape_value_to_assessment';
|
|
8671
|
+
/** The entity type this rule applies to (or `'*'` for all types). */
|
|
8672
|
+
type: string;
|
|
8673
|
+
/** Key inside `properties` whose bare number is wrapped (stays in the bag). */
|
|
8674
|
+
property: string;
|
|
8675
|
+
/** The assessment scale to label the value on (e.g. `impact_5`, `importance_5`). */
|
|
8676
|
+
scale_id: string;
|
|
8677
|
+
/** Human-readable explanation surfaced in load-time warnings. */
|
|
8678
|
+
reason: string;
|
|
8660
8679
|
};
|
|
8661
8680
|
/**
|
|
8662
8681
|
* Version-scoped property migrations. Same convention as `UPG_MIGRATIONS`:
|
|
@@ -8688,6 +8707,12 @@ type UPGPropertyMigrationChange = {
|
|
|
8688
8707
|
property: string;
|
|
8689
8708
|
to_property?: string;
|
|
8690
8709
|
value_changed: boolean;
|
|
8710
|
+
} | {
|
|
8711
|
+
kind: 'reshaped_to_assessment';
|
|
8712
|
+
property: string;
|
|
8713
|
+
scale_id: string;
|
|
8714
|
+
value: number;
|
|
8715
|
+
label: string;
|
|
8691
8716
|
};
|
|
8692
8717
|
/**
|
|
8693
8718
|
* Apply property migrations to a single node. Returns the (possibly new) node
|
|
@@ -21413,7 +21438,7 @@ declare function isCanonical(text: string): boolean;
|
|
|
21413
21438
|
* it stamps the `upg_version` field of every `.upg` file written by the SDK.
|
|
21414
21439
|
* The `check:version-lockstep` gate enforces this at release time.
|
|
21415
21440
|
*/
|
|
21416
|
-
declare const UPG_VERSION: "0.10.
|
|
21441
|
+
declare const UPG_VERSION: "0.10.2";
|
|
21417
21442
|
/**
|
|
21418
21443
|
* The `.upg` JSON document format version. Written to the `upg_version` field.
|
|
21419
21444
|
* Evolves independently from `UPG_VERSION` (the catalogue version).
|
package/dist/index.js
CHANGED
|
@@ -1145,6 +1145,10 @@ var UPG_EDGE_CATALOG = {
|
|
|
1145
1145
|
// would be a separate catalog-mechanic change).
|
|
1146
1146
|
competitive_analysis_dimensioned_by_classification_axis: { forward_verb: "dimensioned_by", reverse_verb: "dimensions", classification: "hierarchy", source_type: "competitive_analysis", target_type: "classification_axis" },
|
|
1147
1147
|
classification_axis_includes_classification_value: { forward_verb: "includes", reverse_verb: "value_of", classification: "hierarchy", source_type: "classification_axis", target_type: "classification_value" },
|
|
1148
|
+
// 0.10.2: also dual-registered as a cross-edge (UPG_CROSS_EDGE_TYPES) so a
|
|
1149
|
+
// competitor can be classified directly against a `registry/{classification_value}`
|
|
1150
|
+
// canonical, eliminating the per-graph taxonomy node. Within-graph (the catalogue
|
|
1151
|
+
// case) here; cross-product against the registry canonical via create_cross_product_edge.
|
|
1148
1152
|
competitor_classified_as_classification_value: { forward_verb: "classified_as", reverse_verb: "classification_of", classification: "semantic", source_type: "competitor", target_type: "classification_value" },
|
|
1149
1153
|
persona_anti_fit_for_classification_value: { forward_verb: "is_anti_fit_for", reverse_verb: "should_not_be_picked_by", classification: "semantic", source_type: "persona", target_type: "classification_value" },
|
|
1150
1154
|
persona_anti_fit_for_product: { forward_verb: "is_anti_fit_for", reverse_verb: "should_not_be_picked_by", classification: "semantic", source_type: "persona", target_type: "product" },
|
|
@@ -3040,7 +3044,8 @@ var UPG_CROSS_EDGE_TYPES = [
|
|
|
3040
3044
|
"primitive_stored_as_data_type",
|
|
3041
3045
|
"feature_rivals_competitor_feature",
|
|
3042
3046
|
"competitor_signal_maps_to_feature",
|
|
3043
|
-
"competitor_signal_surfaces_opportunity"
|
|
3047
|
+
"competitor_signal_surfaces_opportunity",
|
|
3048
|
+
"competitor_classified_as_classification_value"
|
|
3044
3049
|
];
|
|
3045
3050
|
var REGISTRY_PRODUCT_ID = "registry";
|
|
3046
3051
|
|
|
@@ -7250,6 +7255,34 @@ function getDeprecatedTypes() {
|
|
|
7250
7255
|
return deprecated;
|
|
7251
7256
|
}
|
|
7252
7257
|
var UPG_PROPERTY_MIGRATIONS = {
|
|
7258
|
+
// ── v0.10.2: market_intelligence number -> assessment reshape ──────────────
|
|
7259
|
+
//
|
|
7260
|
+
// The v0.10.0 property-registry generator fix (#43) corrected several property
|
|
7261
|
+
// types that interfaces already declared as `UPGAssessment` but the generator
|
|
7262
|
+
// had emitted loosely. A pre-0.10.0 graph that stored a bare number for
|
|
7263
|
+
// `market_trend.impact` / `relevance` is now invalid (the schema wants
|
|
7264
|
+
// `{value,label}`). These rules wrap the bare number on its canonical scale so
|
|
7265
|
+
// the migration is one command, not a hand-reshape. The enum tightenings the
|
|
7266
|
+
// same #43 fix surfaced (data_flow.direction, integration_pattern.pattern_type,
|
|
7267
|
+
// api_contract.protocol, service.service_type) already have rules under 0.9.12;
|
|
7268
|
+
// 0.10.2 also makes ALL of them visible to validate_graph (they were applied by
|
|
7269
|
+
// migrate_properties but never surfaced as a fixable drift).
|
|
7270
|
+
"0.10.2": [
|
|
7271
|
+
{
|
|
7272
|
+
kind: "reshape_value_to_assessment",
|
|
7273
|
+
type: "market_trend",
|
|
7274
|
+
property: "impact",
|
|
7275
|
+
scale_id: "impact_5",
|
|
7276
|
+
reason: "market_trend.impact is a UPGAssessment (impact_5); the 0.10.0 generator fix (#43) tightened it from a bare number. A legacy numeric value wraps to {value,label} on impact_5."
|
|
7277
|
+
},
|
|
7278
|
+
{
|
|
7279
|
+
kind: "reshape_value_to_assessment",
|
|
7280
|
+
type: "market_trend",
|
|
7281
|
+
property: "relevance",
|
|
7282
|
+
scale_id: "importance_5",
|
|
7283
|
+
reason: "market_trend.relevance is a UPGAssessment (importance_5); the 0.10.0 generator fix (#43) tightened it from a bare number. A legacy numeric value wraps to {value,label} on importance_5."
|
|
7284
|
+
}
|
|
7285
|
+
],
|
|
7253
7286
|
// ── v0.9.14: drop the key_result kr_status / status twin (A2) ──────────────
|
|
7254
7287
|
//
|
|
7255
7288
|
// key_result carried BOTH a lifecycle `status` and a `kr_status` property with
|
|
@@ -7822,6 +7855,26 @@ function migrateNodeProperties(node, fromVersion, toVersion) {
|
|
|
7822
7855
|
mutated = true;
|
|
7823
7856
|
break;
|
|
7824
7857
|
}
|
|
7858
|
+
case "reshape_value_to_assessment": {
|
|
7859
|
+
const props = workingNode.properties;
|
|
7860
|
+
if (!props || !(m.property in props)) break;
|
|
7861
|
+
const oldValue = props[m.property];
|
|
7862
|
+
let num = null;
|
|
7863
|
+
if (typeof oldValue === "number" && Number.isFinite(oldValue)) num = oldValue;
|
|
7864
|
+
else if (typeof oldValue === "string" && oldValue.trim() !== "" && Number.isFinite(Number(oldValue))) {
|
|
7865
|
+
num = Number(oldValue);
|
|
7866
|
+
}
|
|
7867
|
+
if (num === null) break;
|
|
7868
|
+
const label = getScale(m.scale_id)?.points.find((p) => p.value === num)?.label ?? String(num);
|
|
7869
|
+
const nextProps = {
|
|
7870
|
+
...props,
|
|
7871
|
+
[m.property]: { value: num, label, scale_id: m.scale_id }
|
|
7872
|
+
};
|
|
7873
|
+
workingNode.properties = nextProps;
|
|
7874
|
+
mutated = true;
|
|
7875
|
+
changes.push({ kind: "reshaped_to_assessment", property: m.property, scale_id: m.scale_id, value: num, label });
|
|
7876
|
+
break;
|
|
7877
|
+
}
|
|
7825
7878
|
}
|
|
7826
7879
|
}
|
|
7827
7880
|
}
|
|
@@ -28376,7 +28429,7 @@ function isCanonical(text) {
|
|
|
28376
28429
|
}
|
|
28377
28430
|
|
|
28378
28431
|
// src/index.ts
|
|
28379
|
-
var UPG_VERSION = "0.10.
|
|
28432
|
+
var UPG_VERSION = "0.10.2";
|
|
28380
28433
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
28381
28434
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
28382
28435
|
var UPG_TYPES = getTypes();
|