@unified-product-graph/core 0.9.8 → 0.9.10
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 +36 -0
- package/dist/index.cjs +342 -136
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +245 -210
- package/dist/index.d.ts +245 -210
- package/dist/index.js +341 -136
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -182,6 +182,7 @@ __export(index_exports, {
|
|
|
182
182
|
resolveEntityType: () => resolveEntityType,
|
|
183
183
|
resolveLabel: () => resolveLabel,
|
|
184
184
|
resolveSlugCollision: () => resolveSlugCollision,
|
|
185
|
+
ringOrderedDomainIds: () => ringOrderedDomainIds,
|
|
185
186
|
rotateSlug: () => rotateSlug,
|
|
186
187
|
serializeCanonical: () => serializeCanonical,
|
|
187
188
|
validateProductStageStrict: () => validateProductStageStrict,
|
|
@@ -238,8 +239,8 @@ var UPG_DOMAINS = [
|
|
|
238
239
|
{
|
|
239
240
|
id: "validation",
|
|
240
241
|
label: "Validation",
|
|
241
|
-
description: "Testing ideas before committing to build them. Hypotheses state testable beliefs. Experiments run the tests. Evidence captures what was observed. Learnings distill what was understood.
|
|
242
|
-
types: ["hypothesis", "experiment", "experiment_plan", "experiment_run", "learning", "
|
|
242
|
+
description: "Testing ideas before committing to build them. Hypotheses state testable beliefs. Experiment plans structure the validation design. Experiments run the tests, with experiment runs capturing replication. Evidence captures what was observed. Learnings distill what was understood. Research plans coordinate broader investigation. Consumes opportunities from Discovery and insights from User Research, producing evidence that informs Strategy and Product Specification.",
|
|
243
|
+
types: ["hypothesis", "experiment", "experiment_plan", "experiment_run", "learning", "evidence", "research_plan"]
|
|
243
244
|
},
|
|
244
245
|
{
|
|
245
246
|
id: "market_intelligence",
|
|
@@ -484,8 +485,9 @@ var UPG_DOMAINS = [
|
|
|
484
485
|
{
|
|
485
486
|
id: "testing",
|
|
486
487
|
label: "Quality Assurance",
|
|
487
|
-
description: "Verifying your product works correctly. Test suites group related tests. Test cases define individual checks. QA sessions capture exploratory testing. Regression tests guard against regressions. Test coverage reports measure completeness. Test environments define where tests run. Test results record outcomes. Validates Engineering (code quality) and Product Specification (acceptance criteria). Feeds DevOps (release confidence).",
|
|
488
|
+
description: "Verifying your product works correctly. Test plans define the verification approach (scope, environments, pass criteria). Test suites group related tests. Test cases define individual checks. QA sessions capture exploratory testing. Regression tests guard against regressions. Test coverage reports measure completeness. Test environments define where tests run. Test results record outcomes. Validates Engineering (code quality) and Product Specification (acceptance criteria). Feeds DevOps (release confidence).",
|
|
488
489
|
types: [
|
|
490
|
+
"test_plan",
|
|
489
491
|
"test_suite",
|
|
490
492
|
"test_case",
|
|
491
493
|
"qa_session",
|
|
@@ -524,7 +526,7 @@ var UPG_DOMAINS = [
|
|
|
524
526
|
{
|
|
525
527
|
id: "ai",
|
|
526
528
|
label: "AI & Machine Learning",
|
|
527
|
-
description: "AI and machine learning capabilities within your product. AI models track deployed models. Prompt versions manage
|
|
529
|
+
description: "AI and machine learning capabilities within your product. AI models track deployed models. Prompt templates define reusable prompts; prompt versions manage their evolution. Eval benchmarks and eval runs measure quality. AI cost trackers monitor spend. Hallucination reports flag reliability issues. AI guardrails set safety boundaries. Model comparisons evaluate alternatives. AI experiments test new approaches. AI datasets track training data. AI traces log inference chains. Connects to Engineering, Data & Analytics, and Product Specification.",
|
|
528
530
|
types: [
|
|
529
531
|
"ai_model",
|
|
530
532
|
"prompt_version",
|
|
@@ -747,15 +749,23 @@ var UPG_ENTITY_META = [
|
|
|
747
749
|
{ name: "hypothesis", type_id: "ent_027", maturity: "stable", since: "0.1.0" },
|
|
748
750
|
{ name: "hypothesis_claim", type_id: "ent_344", maturity: "deprecated", since: "0.2.8", deprecated_in: "0.4.0", replacement: "hypothesis" },
|
|
749
751
|
{ name: "hypothesis_evidence", type_id: "ent_345", maturity: "deprecated", since: "0.2.8", deprecated_in: "0.4.0", replacement: "evidence" },
|
|
750
|
-
// `experiment` is canonical. It has its own property schema
|
|
752
|
+
// `experiment` is canonical (UPG-664). It has its own property schema
|
|
751
753
|
// (method, start_date, end_date, sample_size, expected_lift) and is the
|
|
752
|
-
// canonical
|
|
753
|
-
//
|
|
754
|
-
//
|
|
754
|
+
// canonical unit of a structured test. The validation flow is
|
|
755
|
+
// `hypothesis → experiment_plan → experiment → experiment_run`: the plan is
|
|
756
|
+
// the validation design, the experiment is the structured test, the run is
|
|
757
|
+
// the optional multi-run/replication child.
|
|
755
758
|
{ name: "experiment", type_id: "ent_028", maturity: "stable", since: "0.1.0" },
|
|
756
|
-
|
|
759
|
+
// experiment_plan graduated proposed → stable (UPG-664). It is the canonical
|
|
760
|
+
// validation PLAN type — it absorbed `test_plan`'s planning properties
|
|
761
|
+
// (method / success_criteria / sample_size) when `test_plan` re-homed to the
|
|
762
|
+
// QA/testing domain (UPG-678).
|
|
763
|
+
{ name: "experiment_plan", type_id: "ent_340", maturity: "stable", since: "0.2.6" },
|
|
757
764
|
{ name: "experiment_run", type_id: "ent_341", maturity: "proposed", since: "0.2.6" },
|
|
758
765
|
{ name: "learning", type_id: "ent_029", maturity: "stable", since: "0.1.0" },
|
|
766
|
+
// test_plan re-homed validation → testing/QA (UPG-678). It is the QA
|
|
767
|
+
// verification-procedure plan (test scope / environments / pass criteria);
|
|
768
|
+
// its former validation-planning role is carried by experiment_plan.
|
|
759
769
|
{ name: "test_plan", type_id: "ent_030", maturity: "stable", since: "0.1.0" },
|
|
760
770
|
{ name: "evidence", type_id: "ent_031", maturity: "stable", since: "0.1.0" },
|
|
761
771
|
{ name: "research_plan", type_id: "ent_032", maturity: "stable", since: "0.1.0" },
|
|
@@ -889,7 +899,7 @@ var UPG_ENTITY_META = [
|
|
|
889
899
|
{ name: "behavioral_segment", type_id: "ent_111", maturity: "stable", since: "0.1.0" },
|
|
890
900
|
{ name: "segment", type_id: "ent_338", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.2.0", replacement: "behavioral_segment" },
|
|
891
901
|
{ name: "growth_loop", type_id: "ent_112", maturity: "stable", since: "0.1.0" },
|
|
892
|
-
{ name: "growth_experiment", type_id: "ent_113", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "
|
|
902
|
+
{ name: "growth_experiment", type_id: "ent_113", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "experiment" },
|
|
893
903
|
{ name: "variant", type_id: "ent_114", maturity: "stable", since: "0.1.0" },
|
|
894
904
|
{ name: "attribution_model", type_id: "ent_115", maturity: "stable", since: "0.1.0" },
|
|
895
905
|
// ── Business Model ──
|
|
@@ -939,7 +949,7 @@ var UPG_ENTITY_META = [
|
|
|
939
949
|
{ name: "metric_definition", type_id: "ent_154", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "metric" },
|
|
940
950
|
{ name: "event_schema", type_id: "ent_155", maturity: "stable", since: "0.1.0" },
|
|
941
951
|
{ name: "dashboard", type_id: "ent_156", maturity: "stable", since: "0.1.0" },
|
|
942
|
-
{ name: "ab_test", type_id: "ent_157", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "
|
|
952
|
+
{ name: "ab_test", type_id: "ent_157", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "experiment" },
|
|
943
953
|
{ name: "data_model", type_id: "ent_158", maturity: "stable", since: "0.1.0" },
|
|
944
954
|
{ name: "data_quality_rule", type_id: "ent_159", maturity: "stable", since: "0.1.0" },
|
|
945
955
|
{ name: "data_product", type_id: "ent_160", maturity: "stable", since: "0.1.0" },
|
|
@@ -1021,7 +1031,7 @@ var UPG_ENTITY_META = [
|
|
|
1021
1031
|
{ name: "feedback_theme", type_id: "ent_225", maturity: "stable", since: "0.1.0" },
|
|
1022
1032
|
// ── Pricing & Packaging ──
|
|
1023
1033
|
{ name: "pricing_strategy", type_id: "ent_226", maturity: "stable", since: "0.1.0" },
|
|
1024
|
-
{ name: "pricing_experiment", type_id: "ent_227", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "
|
|
1034
|
+
{ name: "pricing_experiment", type_id: "ent_227", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "experiment" },
|
|
1025
1035
|
{ name: "package", type_id: "ent_228", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.2.0", replacement: "pricing_tier" },
|
|
1026
1036
|
{ name: "discount_strategy", type_id: "ent_229", maturity: "stable", since: "0.1.0" },
|
|
1027
1037
|
{ name: "trial_config", type_id: "ent_230", maturity: "stable", since: "0.1.0" },
|
|
@@ -1192,8 +1202,22 @@ var UPG_EDGE_CATALOG = {
|
|
|
1192
1202
|
// `evolved_from` in the reverse lets a feature trace its solution ancestry.
|
|
1193
1203
|
solution_becomes_feature: { forward_verb: "becomes", reverse_verb: "evolved_from", classification: "causal", source_type: "solution", target_type: "feature" },
|
|
1194
1204
|
hypothesis_requires_experiment_plan: { forward_verb: "requires", reverse_verb: "planned_for", classification: "causal", source_type: "hypothesis", target_type: "experiment_plan" },
|
|
1195
|
-
|
|
1205
|
+
// (UPG-664) V4: close the stable canonical loop directly on `experiment`.
|
|
1206
|
+
// Before this, resolve_edge_for_pair(hypothesis, experiment) and the reverse
|
|
1207
|
+
// were both null — the stable experiment could not attach to the hypothesis
|
|
1208
|
+
// it tests without adopting the proposed run type.
|
|
1209
|
+
hypothesis_tested_by_experiment: { forward_verb: "tested_by", reverse_verb: "tests", classification: "causal", source_type: "hypothesis", target_type: "experiment" },
|
|
1210
|
+
experiment_validates_hypothesis: { forward_verb: "validates", reverse_verb: "validated_by", classification: "causal", source_type: "experiment", target_type: "hypothesis" },
|
|
1196
1211
|
hypothesis_investigated_via_research_plan: { forward_verb: "investigated_via", reverse_verb: "investigates", classification: "hierarchy", source_type: "hypothesis", target_type: "research_plan" },
|
|
1212
|
+
// (UPG-678) V8: a research insight can seed a hypothesis directly. The region
|
|
1213
|
+
// says validation consumes `insight` from user_research, but the only paths
|
|
1214
|
+
// in were via solution/learning/assumption.
|
|
1215
|
+
insight_generates_hypothesis: { forward_verb: "generates", reverse_verb: "generated_from", classification: "cross-domain", source_type: "insight", target_type: "hypothesis" },
|
|
1216
|
+
// (UPG-678) V7: the validation-side research plan is conducted as the
|
|
1217
|
+
// user_research-side research study. Both sit in the
|
|
1218
|
+
// discovery_research_validation region but had no connecting edge; the plan
|
|
1219
|
+
// jumped straight to `participant`, bypassing the study container.
|
|
1220
|
+
research_plan_conducted_as_research_study: { forward_verb: "conducted_as", reverse_verb: "conducts", classification: "cross-domain", source_type: "research_plan", target_type: "research_study" },
|
|
1197
1221
|
experiment_run_produces_learning: { forward_verb: "produces", reverse_verb: "learned_from", classification: "causal", source_type: "experiment_run", target_type: "learning" },
|
|
1198
1222
|
experiment_run_yields_evidence: { forward_verb: "yields", reverse_verb: "supports", classification: "causal", source_type: "experiment_run", target_type: "evidence" },
|
|
1199
1223
|
// (v0.2.7 closure) the legacy duplicate pair
|
|
@@ -1227,7 +1251,11 @@ var UPG_EDGE_CATALOG = {
|
|
|
1227
1251
|
// canonical edge, not a foreign-key property (the v0.2.6 ExperimentPlan
|
|
1228
1252
|
// interface left this slot pending in line with the principle).
|
|
1229
1253
|
experiment_plan_targets_metric: { forward_verb: "targets", reverse_verb: "targeted_by_plan", classification: "cross-domain", source_type: "experiment_plan", target_type: "metric" },
|
|
1230
|
-
|
|
1254
|
+
// (UPG-664) The validation plan designs the experiment it produces. This
|
|
1255
|
+
// replaces the backwards `experiment_has_plan` (experiment → experiment_plan):
|
|
1256
|
+
// the chain now reads hypothesis → experiment_plan → experiment → experiment_run,
|
|
1257
|
+
// with experiment_plan the owning parent of experiment.
|
|
1258
|
+
experiment_plan_designs_experiment: { forward_verb: "designs", reverse_verb: "designed_by", classification: "hierarchy", source_type: "experiment_plan", target_type: "experiment" },
|
|
1231
1259
|
experiment_executed_as_experiment_run: { forward_verb: "executed_as", reverse_verb: "execution_of", classification: "hierarchy", source_type: "experiment", target_type: "experiment_run" },
|
|
1232
1260
|
experiment_produces_learning: { forward_verb: "produces", reverse_verb: "produced_by", classification: "causal", source_type: "experiment", target_type: "learning" },
|
|
1233
1261
|
experiment_produces_evidence: { forward_verb: "produces", reverse_verb: "produced_by", classification: "causal", source_type: "experiment", target_type: "evidence" },
|
|
@@ -1352,11 +1380,15 @@ var UPG_EDGE_CATALOG = {
|
|
|
1352
1380
|
product_holds_assumption: { forward_verb: "holds", reverse_verb: "held_by", classification: "semantic", source_type: "product", target_type: "assumption" },
|
|
1353
1381
|
product_measures_with_metric: { forward_verb: "measures_with", reverse_verb: "measures", classification: "hierarchy", source_type: "product", target_type: "metric" },
|
|
1354
1382
|
outcome_measured_by_metric: { forward_verb: "measured_by", reverse_verb: "measures", classification: "hierarchy", source_type: "outcome", target_type: "metric" },
|
|
1355
|
-
|
|
1383
|
+
// (UPG-677) outcome_tracked_by_metric retired — near-synonym of
|
|
1384
|
+
// outcome_measured_by_metric (the kept canonical key). Captain's lean =
|
|
1385
|
+
// collapse. See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
1356
1386
|
objective_achieved_through_key_result: { forward_verb: "achieved_through", reverse_verb: "achieves", classification: "hierarchy", source_type: "objective", target_type: "key_result" },
|
|
1357
1387
|
objective_measured_by_metric: { forward_verb: "measured_by", reverse_verb: "measures", classification: "hierarchy", source_type: "objective", target_type: "metric" },
|
|
1358
1388
|
key_result_quantified_by_metric: { forward_verb: "quantified_by", reverse_verb: "quantifies", classification: "hierarchy", source_type: "key_result", target_type: "metric" },
|
|
1359
|
-
|
|
1389
|
+
// (UPG-677) key_result_tracked_by_metric retired — near-synonym of
|
|
1390
|
+
// key_result_quantified_by_metric (the kept canonical key). Captain's lean =
|
|
1391
|
+
// collapse. See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
1360
1392
|
vision_realised_through_mission: { forward_verb: "realised_through", reverse_verb: "realises", classification: "hierarchy", source_type: "vision", target_type: "mission" },
|
|
1361
1393
|
mission_supported_by_strategic_pillar: { forward_verb: "supported_by", reverse_verb: "supports", classification: "hierarchy", source_type: "mission", target_type: "strategic_pillar" },
|
|
1362
1394
|
strategic_pillar_organises_strategic_theme: { forward_verb: "organises", reverse_verb: "organised_by", classification: "hierarchy", source_type: "strategic_pillar", target_type: "strategic_theme" },
|
|
@@ -1380,17 +1412,20 @@ var UPG_EDGE_CATALOG = {
|
|
|
1380
1412
|
// make them measurable. Direct link means a dashboard can surface KRs next
|
|
1381
1413
|
// to the theme without traversing objective.
|
|
1382
1414
|
//
|
|
1383
|
-
// `
|
|
1415
|
+
// `strategic_theme_contains_objective`: the OKR containment edge (UPG-676,
|
|
1416
|
+
// renamed from the malformed `objective_rolls_up_to_strategic_theme`).
|
|
1384
1417
|
// an objective is the specific quarterly bet *within* a theme. strategic_theme
|
|
1385
1418
|
// is the broader multi-quarter focus area; objective is subordinate.
|
|
1386
1419
|
// Direction: strategic_theme → objective (parent → child, per UPG hierarchy
|
|
1387
|
-
// convention where source is the parent). The
|
|
1420
|
+
// convention where source is the parent). The key now reads source-first
|
|
1421
|
+
// (strategic_theme), the forward verb is the clean `contains` (was the
|
|
1422
|
+
// malformed `contains_objective`), and the reverse verb `rolls_up_to`
|
|
1388
1423
|
// surfaces the upward-rollup read. Mirrors `strategic_pillar_organises_
|
|
1389
1424
|
// strategic_theme` (pillar → theme), completing the strategic cascade:
|
|
1390
1425
|
// strategic_pillar → strategic_theme → objective → key_result.
|
|
1391
1426
|
strategic_theme_delivers_outcome: { forward_verb: "delivers", reverse_verb: "delivered_by", classification: "causal", source_type: "strategic_theme", target_type: "outcome" },
|
|
1392
1427
|
strategic_theme_measured_by_key_result: { forward_verb: "measured_by", reverse_verb: "measures", classification: "causal", source_type: "strategic_theme", target_type: "key_result" },
|
|
1393
|
-
|
|
1428
|
+
strategic_theme_contains_objective: { forward_verb: "contains", reverse_verb: "rolls_up_to", classification: "hierarchy", source_type: "strategic_theme", target_type: "objective" },
|
|
1394
1429
|
initiative_assumes_assumption: { forward_verb: "assumes", reverse_verb: "assumed_by", classification: "hierarchy", source_type: "initiative", target_type: "assumption" },
|
|
1395
1430
|
initiative_drives_outcome: { forward_verb: "drives", reverse_verb: "driven_by", classification: "cross-domain", source_type: "initiative", target_type: "outcome" },
|
|
1396
1431
|
capability_enables_value_stream: { forward_verb: "enables", reverse_verb: "enabled_by", classification: "cross-domain", source_type: "capability", target_type: "value_stream" },
|
|
@@ -1695,7 +1730,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
1695
1730
|
threat_model_surfaces_vulnerability: { forward_verb: "surfaces", reverse_verb: "surfaced_by", classification: "hierarchy", source_type: "threat_model", target_type: "vulnerability" },
|
|
1696
1731
|
product_enforces_security_control: { forward_verb: "enforces", reverse_verb: "enforced_by", classification: "hierarchy", source_type: "product", target_type: "security_control" },
|
|
1697
1732
|
product_governed_by_security_policy: { forward_verb: "governed_by", reverse_verb: "governs", classification: "hierarchy", source_type: "product", target_type: "security_policy" },
|
|
1698
|
-
|
|
1733
|
+
// (UPG-677) product_experiences_incident_hierarchy retired — byte-identical
|
|
1734
|
+
// shadow of product_experiences_incident (the clean key). See
|
|
1735
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
1699
1736
|
product_tested_by_penetration_test: { forward_verb: "tested_by", reverse_verb: "tests", classification: "hierarchy", source_type: "product", target_type: "penetration_test" },
|
|
1700
1737
|
product_reviewed_by_security_review: { forward_verb: "reviewed_by", reverse_verb: "reviews", classification: "hierarchy", source_type: "product", target_type: "security_review" },
|
|
1701
1738
|
product_classifies_data_with_data_classification: { forward_verb: "classifies_data_with", reverse_verb: "classifies_data_for", classification: "hierarchy", source_type: "product", target_type: "data_classification" },
|
|
@@ -1716,6 +1753,12 @@ var UPG_EDGE_CATALOG = {
|
|
|
1716
1753
|
vulnerability_discovered_by_penetration_test: { forward_verb: "discovered_by", reverse_verb: "discovers", classification: "cross-domain", source_type: "vulnerability", target_type: "penetration_test" },
|
|
1717
1754
|
data_classification_applies_to_data_source: { forward_verb: "applies_to", reverse_verb: "classified_by", classification: "cross-domain", source_type: "data_classification", target_type: "data_source" },
|
|
1718
1755
|
// 3.4 Quality Assurance & Testing Domain
|
|
1756
|
+
// (UPG-678) test_plan re-homed validation → QA. It is the QA planning layer:
|
|
1757
|
+
// the product owns its test plans; each plan is carried out by the suites it
|
|
1758
|
+
// groups and specifies the environments it exercises.
|
|
1759
|
+
product_plans_qa_via_test_plan: { forward_verb: "plans_qa_via", reverse_verb: "plans_qa_for", classification: "hierarchy", source_type: "product", target_type: "test_plan" },
|
|
1760
|
+
test_plan_executed_by_test_suite: { forward_verb: "executed_by", reverse_verb: "executes", classification: "hierarchy", source_type: "test_plan", target_type: "test_suite" },
|
|
1761
|
+
test_plan_specifies_test_environment: { forward_verb: "specifies", reverse_verb: "specified_by", classification: "hierarchy", source_type: "test_plan", target_type: "test_environment" },
|
|
1719
1762
|
product_maintains_test_suite: { forward_verb: "maintains", reverse_verb: "maintained_by", classification: "hierarchy", source_type: "product", target_type: "test_suite" },
|
|
1720
1763
|
test_suite_contains_test_case: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "test_suite", target_type: "test_case" },
|
|
1721
1764
|
product_undergoes_qa_session: { forward_verb: "undergoes", reverse_verb: "conducted_on", classification: "hierarchy", source_type: "product", target_type: "qa_session" },
|
|
@@ -1747,7 +1790,12 @@ var UPG_EDGE_CATALOG = {
|
|
|
1747
1790
|
a11y_audit_covers_feature: { forward_verb: "covers", reverse_verb: "covered_by", classification: "cross-domain", source_type: "a11y_audit", target_type: "feature" },
|
|
1748
1791
|
// 3.6 AI/ML Operations Domain
|
|
1749
1792
|
product_powered_by_ai_model: { forward_verb: "powered_by", reverse_verb: "powers", classification: "hierarchy", source_type: "product", target_type: "ai_model" },
|
|
1750
|
-
|
|
1793
|
+
// (UPG-665) The prompt abstraction is corrected to ai_model → prompt_template
|
|
1794
|
+
// → prompt_version. The model defines templates; each template contains its
|
|
1795
|
+
// versions. This replaces the inverted ai_model → prompt_version ownership
|
|
1796
|
+
// and the backwards prompt_version → prompt_template edge.
|
|
1797
|
+
ai_model_defines_prompt_template: { forward_verb: "defines", reverse_verb: "defined_by", classification: "hierarchy", source_type: "ai_model", target_type: "prompt_template" },
|
|
1798
|
+
prompt_template_contains_prompt_version: { forward_verb: "contains", reverse_verb: "version_of", classification: "hierarchy", source_type: "prompt_template", target_type: "prompt_version" },
|
|
1751
1799
|
ai_model_benchmarked_by_eval_benchmark: { forward_verb: "benchmarked_by", reverse_verb: "benchmarks", classification: "hierarchy", source_type: "ai_model", target_type: "eval_benchmark" },
|
|
1752
1800
|
eval_benchmark_executed_as_eval_run: { forward_verb: "executed_as", reverse_verb: "executes", classification: "hierarchy", source_type: "eval_benchmark", target_type: "eval_run" },
|
|
1753
1801
|
ai_model_costed_by_ai_cost_tracker: { forward_verb: "costed_by", reverse_verb: "costs", classification: "hierarchy", source_type: "ai_model", target_type: "ai_cost_tracker" },
|
|
@@ -1755,7 +1803,10 @@ var UPG_EDGE_CATALOG = {
|
|
|
1755
1803
|
ai_model_constrained_by_ai_guardrail: { forward_verb: "constrained_by", reverse_verb: "constrains", classification: "hierarchy", source_type: "ai_model", target_type: "ai_guardrail" },
|
|
1756
1804
|
product_compared_via_model_comparison: { forward_verb: "compared_via", reverse_verb: "compares", classification: "hierarchy", source_type: "product", target_type: "model_comparison" },
|
|
1757
1805
|
ai_model_compared_in_model_comparison: { forward_verb: "compared_in", reverse_verb: "compares", classification: "hierarchy", source_type: "ai_model", target_type: "model_comparison" },
|
|
1758
|
-
|
|
1806
|
+
// (UPG-665, AI-10) prompt_version self-ordering: track iteration order with a
|
|
1807
|
+
// real edge, not just a string property — the domain's own anti-pattern is
|
|
1808
|
+
// "version prompts like code".
|
|
1809
|
+
prompt_version_supersedes_prompt_version: { forward_verb: "supersedes", reverse_verb: "superseded_by", classification: "semantic", source_type: "prompt_version", target_type: "prompt_version" },
|
|
1759
1810
|
eval_benchmark_measures_feature: { forward_verb: "measures", reverse_verb: "measured_by", classification: "cross-domain", source_type: "eval_benchmark", target_type: "feature" },
|
|
1760
1811
|
ai_guardrail_enforces_security_policy: { forward_verb: "enforces", reverse_verb: "enforced_by", classification: "cross-domain", source_type: "ai_guardrail", target_type: "security_policy" },
|
|
1761
1812
|
model_comparison_informs_decision: { forward_verb: "informs", reverse_verb: "informed_by", classification: "cross-domain", source_type: "model_comparison", target_type: "decision" },
|
|
@@ -1763,6 +1814,18 @@ var UPG_EDGE_CATALOG = {
|
|
|
1763
1814
|
ai_model_evaluated_through_ai_experiment: { forward_verb: "evaluated_through", reverse_verb: "evaluates", classification: "hierarchy", source_type: "ai_model", target_type: "ai_experiment" },
|
|
1764
1815
|
ai_model_trained_on_ai_dataset: { forward_verb: "trained_on", reverse_verb: "trains", classification: "hierarchy", source_type: "ai_model", target_type: "ai_dataset" },
|
|
1765
1816
|
ai_model_produces_ai_trace: { forward_verb: "produces", reverse_verb: "produced_by", classification: "causal", source_type: "ai_model", target_type: "ai_trace" },
|
|
1817
|
+
// (UPG-665) Observability bridges — turn four sinks into wired evidence and
|
|
1818
|
+
// close the Model Evaluation Loop.
|
|
1819
|
+
// AI-3: an eval_run can reach the model and prompt version it judged.
|
|
1820
|
+
eval_run_evaluates_ai_model: { forward_verb: "evaluates", reverse_verb: "evaluated_by", classification: "cross-domain", source_type: "eval_run", target_type: "ai_model" },
|
|
1821
|
+
eval_run_scores_prompt_version: { forward_verb: "scores", reverse_verb: "scored_by", classification: "cross-domain", source_type: "eval_run", target_type: "prompt_version" },
|
|
1822
|
+
// AI-5: a hallucination_report reaches the trace that produced it and its root cause.
|
|
1823
|
+
hallucination_report_traces_to_ai_trace: { forward_verb: "traces_to", reverse_verb: "traced_by", classification: "cross-domain", source_type: "hallucination_report", target_type: "ai_trace" },
|
|
1824
|
+
hallucination_report_caused_by_root_cause: { forward_verb: "caused_by", reverse_verb: "causes", classification: "cross-domain", source_type: "hallucination_report", target_type: "root_cause" },
|
|
1825
|
+
// AI-6: an ai_trace reaches the prompt version it executed.
|
|
1826
|
+
ai_trace_executed_prompt_version: { forward_verb: "executed", reverse_verb: "executed_in", classification: "cross-domain", source_type: "ai_trace", target_type: "prompt_version" },
|
|
1827
|
+
// AI-4/AI-11: an ai_dataset carries provenance to its data source.
|
|
1828
|
+
ai_dataset_sourced_from_data_source: { forward_verb: "sourced_from", reverse_verb: "sources", classification: "cross-domain", source_type: "ai_dataset", target_type: "data_source" },
|
|
1766
1829
|
// 3.7 Agentic Workflows & Process Domain
|
|
1767
1830
|
product_automated_via_workflow_template: { forward_verb: "automated_via", reverse_verb: "automates", classification: "hierarchy", source_type: "product", target_type: "workflow_template" },
|
|
1768
1831
|
workflow_template_executed_as_workflow_run: { forward_verb: "executed_as", reverse_verb: "executes", classification: "hierarchy", source_type: "workflow_template", target_type: "workflow_run" },
|
|
@@ -1800,7 +1863,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
1800
1863
|
// variant is owned by growth_campaign in the hierarchy; experiments
|
|
1801
1864
|
// test them via a semantic relationship.
|
|
1802
1865
|
experiment_run_tests_variant: { forward_verb: "tests", reverse_verb: "tested_in", classification: "semantic", source_type: "experiment_run", target_type: "variant" },
|
|
1803
|
-
|
|
1866
|
+
// (UPG-677) metric_decomposed_into_metric retired — tense-twin of
|
|
1867
|
+
// metric_decomposes_into_metric (the active-voice canonical key). See
|
|
1868
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
1804
1869
|
metric_drives_metric: { forward_verb: "drives", reverse_verb: "driven_by", classification: "causal", source_type: "metric", target_type: "metric" },
|
|
1805
1870
|
funnel_step_reveals_need: { forward_verb: "reveals", reverse_verb: "visible_in", classification: "cross-domain", source_type: "funnel_step", target_type: "need" },
|
|
1806
1871
|
funnel_step_tracks_event_schema: { forward_verb: "tracks", reverse_verb: "fires_in", classification: "cross-domain", source_type: "funnel_step", target_type: "event_schema" },
|
|
@@ -1829,7 +1894,11 @@ var UPG_EDGE_CATALOG = {
|
|
|
1829
1894
|
business_model_requires_key_resource: { forward_verb: "requires", reverse_verb: "required_by", classification: "hierarchy", source_type: "business_model", target_type: "key_resource" },
|
|
1830
1895
|
business_model_performs_key_activity: { forward_verb: "performs", reverse_verb: "performed_by", classification: "hierarchy", source_type: "business_model", target_type: "key_activity" },
|
|
1831
1896
|
business_model_targets_market_segment: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "business_model", target_type: "market_segment" },
|
|
1832
|
-
|
|
1897
|
+
// (UPG-677) business_model_reaches_via_distribution_channel retired —
|
|
1898
|
+
// near-synonym of business_model_distributes_via_distribution_channel (the
|
|
1899
|
+
// kept canonical key; "distributes_via" is the Business Model Canvas Channels
|
|
1900
|
+
// verb). FLAG: Captain has not separately confirmed this collapse. See
|
|
1901
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
1833
1902
|
business_model_maintains_customer_relationship: { forward_verb: "maintains", reverse_verb: "maintained_by", classification: "hierarchy", source_type: "business_model", target_type: "customer_relationship" },
|
|
1834
1903
|
business_model_distributes_via_distribution_channel: { forward_verb: "distributes_via", reverse_verb: "distributes_for", classification: "hierarchy", source_type: "business_model", target_type: "distribution_channel" },
|
|
1835
1904
|
revenue_stream_tiered_as_pricing_tier: { forward_verb: "tiered_as", reverse_verb: "tiers", classification: "hierarchy", source_type: "revenue_stream", target_type: "pricing_tier" },
|
|
@@ -1851,7 +1920,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
1851
1920
|
// as a `need` with `valence='pain'`; link each pain the proposition
|
|
1852
1921
|
// relieves structurally.
|
|
1853
1922
|
value_proposition_solves_need: { forward_verb: "solves", reverse_verb: "solved_by", classification: "cross-domain", source_type: "value_proposition", target_type: "need" },
|
|
1854
|
-
|
|
1923
|
+
// (UPG-677) value_proposition_targets_persona_cross_domain retired —
|
|
1924
|
+
// byte-identical shadow of value_proposition_targets_persona (the clean key).
|
|
1925
|
+
// See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
1855
1926
|
revenue_stream_drives_metric: { forward_verb: "drives", reverse_verb: "driven_by", classification: "cross-domain", source_type: "revenue_stream", target_type: "metric" },
|
|
1856
1927
|
// Ring 5 structural edges
|
|
1857
1928
|
// (UPG-668, P-I) These three edges name `funnel_step` but were typed against
|
|
@@ -1995,7 +2066,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
1995
2066
|
customer_feedback_reveals_churn_reason: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "hierarchy", source_type: "customer_feedback", target_type: "churn_reason" },
|
|
1996
2067
|
user_flow_contains_customer_journey_stage: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "user_flow", target_type: "customer_journey_stage" },
|
|
1997
2068
|
customer_journey_stage_contains_touchpoint: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "customer_journey_stage", target_type: "touchpoint" },
|
|
1998
|
-
|
|
2069
|
+
// (UPG-677) reverse_verb normalised revealed_by_ticket → revealed_by when the
|
|
2070
|
+
// support_ticket_reveals_need_cross_domain twin was collapsed into this clean key.
|
|
2071
|
+
support_ticket_reveals_need: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "support_ticket", target_type: "need" },
|
|
1999
2072
|
customer_feedback_creates_observation: { forward_verb: "creates", reverse_verb: "created_from_feedback", classification: "cross-domain", source_type: "customer_feedback", target_type: "observation" },
|
|
2000
2073
|
churn_reason_generates_hypothesis: { forward_verb: "generates", reverse_verb: "generated_from_churn", classification: "cross-domain", source_type: "churn_reason", target_type: "hypothesis" },
|
|
2001
2074
|
user_flow_maps_user_journey: { forward_verb: "maps", reverse_verb: "mapped_by", classification: "cross-domain", source_type: "user_flow", target_type: "user_journey" },
|
|
@@ -2007,14 +2080,18 @@ var UPG_EDGE_CATALOG = {
|
|
|
2007
2080
|
customer_health_score_informs_playbook: { forward_verb: "informs", reverse_verb: "informed_by_health_score", classification: "cross-domain", source_type: "customer_health_score", target_type: "playbook" },
|
|
2008
2081
|
customer_feedback_becomes_feature_request: { forward_verb: "becomes", reverse_verb: "originated_from", classification: "cross-domain", source_type: "customer_feedback", target_type: "feature_request" },
|
|
2009
2082
|
support_ticket_reports_bug: { forward_verb: "reports", reverse_verb: "reported_by", classification: "cross-domain", source_type: "support_ticket", target_type: "bug" },
|
|
2010
|
-
|
|
2083
|
+
// (UPG-677) support_ticket_reveals_need_cross_domain retired — near-duplicate
|
|
2084
|
+
// of support_ticket_reveals_need (the clean key, whose reverse_verb is now
|
|
2085
|
+
// revealed_by). See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2011
2086
|
churn_reason_reveals_need: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "churn_reason", target_type: "need" },
|
|
2012
2087
|
// 5.2 Content & Knowledge Domain
|
|
2013
2088
|
product_publishes_content_piece: { forward_verb: "publishes", reverse_verb: "published_by", classification: "hierarchy", source_type: "product", target_type: "content_piece" },
|
|
2014
2089
|
product_documents_in_knowledge_base_article: { forward_verb: "documents_in", reverse_verb: "documented_by", classification: "hierarchy", source_type: "product", target_type: "knowledge_base_article" },
|
|
2015
2090
|
product_expressed_via_brand_asset: { forward_verb: "expressed_via", reverse_verb: "expresses", classification: "hierarchy", source_type: "product", target_type: "brand_asset" },
|
|
2016
2091
|
product_documented_in_document: { forward_verb: "documented_in", reverse_verb: "documents", classification: "hierarchy", source_type: "product", target_type: "document" },
|
|
2017
|
-
|
|
2092
|
+
// (UPG-665) product_prompted_via_prompt_template retired — prompt_template
|
|
2093
|
+
// re-parented product → ai_model (ai_model_defines_prompt_template). See
|
|
2094
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2018
2095
|
product_templated_via_documentation_template: { forward_verb: "templated_via", reverse_verb: "templates", classification: "hierarchy", source_type: "product", target_type: "documentation_template" },
|
|
2019
2096
|
product_records_in_document: { forward_verb: "records_in", reverse_verb: "records", classification: "hierarchy", source_type: "product", target_type: "document" },
|
|
2020
2097
|
content_strategy_scheduled_in_content_calendar: { forward_verb: "scheduled_in", reverse_verb: "schedules", classification: "hierarchy", source_type: "content_strategy", target_type: "content_calendar" },
|
|
@@ -2024,12 +2101,19 @@ var UPG_EDGE_CATALOG = {
|
|
|
2024
2101
|
content_calendar_schedules_knowledge_base_article: { forward_verb: "schedules", reverse_verb: "scheduled_in", classification: "hierarchy", source_type: "content_calendar", target_type: "knowledge_base_article" },
|
|
2025
2102
|
content_calendar_schedules_brand_asset: { forward_verb: "schedules", reverse_verb: "scheduled_in", classification: "hierarchy", source_type: "content_calendar", target_type: "brand_asset" },
|
|
2026
2103
|
content_calendar_schedules_document: { forward_verb: "schedules", reverse_verb: "scheduled_in", classification: "hierarchy", source_type: "content_calendar", target_type: "document" },
|
|
2027
|
-
|
|
2104
|
+
// (UPG-665) content_calendar_schedules_prompt_template retired — prompt_template
|
|
2105
|
+
// re-homed to the ai_model containment tree (it is an AI artefact, not a
|
|
2106
|
+
// content-calendar-scheduled item). See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2028
2107
|
content_calendar_schedules_documentation_template: { forward_verb: "schedules", reverse_verb: "scheduled_in", classification: "hierarchy", source_type: "content_calendar", target_type: "documentation_template" },
|
|
2029
2108
|
content_piece_supports_messaging: { forward_verb: "supports", reverse_verb: "supported_by", classification: "cross-domain", source_type: "content_piece", target_type: "messaging" },
|
|
2030
2109
|
content_piece_part_of_growth_campaign: { forward_verb: "part_of", reverse_verb: "includes", classification: "cross-domain", source_type: "content_piece", target_type: "growth_campaign" },
|
|
2031
2110
|
knowledge_base_article_documents_feature: { forward_verb: "documents", reverse_verb: "documented_by", classification: "cross-domain", source_type: "knowledge_base_article", target_type: "feature" },
|
|
2032
|
-
|
|
2111
|
+
// (UPG-677) changelog_documents_release retired — inverse of the containment
|
|
2112
|
+
// edge release_documented_in_changelog (release → changelog, matching the
|
|
2113
|
+
// hierarchy release: ['changelog']). The "changelog documents release" read is
|
|
2114
|
+
// preserved by that edge's reverse_verb (documents). FLAG: this is the only
|
|
2115
|
+
// inverse pair collapsed; feature↔bug is kept (distinct classification +
|
|
2116
|
+
// semantic). See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2033
2117
|
prompt_template_powers_feature: { forward_verb: "powers", reverse_verb: "powered_by", classification: "cross-domain", source_type: "prompt_template", target_type: "feature" },
|
|
2034
2118
|
content_theme_targets_persona: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "content_theme", target_type: "persona" },
|
|
2035
2119
|
// v0.7.2 (UPG-571 §1): topic-cluster / content-pillar model; themes organize pieces. Connects the isolated `content_theme` AND `content_piece` members.
|
|
@@ -2065,7 +2149,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
2065
2149
|
// 6.1 Team & Organisation Domain
|
|
2066
2150
|
product_staffed_by_team: { forward_verb: "staffed_by", reverse_verb: "staffs", classification: "hierarchy", source_type: "product", target_type: "team" },
|
|
2067
2151
|
product_influenced_by_stakeholder: { forward_verb: "influenced_by", reverse_verb: "influences", classification: "hierarchy", source_type: "product", target_type: "stakeholder" },
|
|
2068
|
-
|
|
2152
|
+
// (UPG-677) product_decided_via_decision_hierarchy retired — duplicate of
|
|
2153
|
+
// product_decided_via_decision (the clean key). See
|
|
2154
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2069
2155
|
product_organised_into_department: { forward_verb: "organised_into", reverse_verb: "organises", classification: "hierarchy", source_type: "product", target_type: "department" },
|
|
2070
2156
|
department_contains_team: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "department", target_type: "team" },
|
|
2071
2157
|
department_includes_stakeholder: { forward_verb: "includes", reverse_verb: "included_in", classification: "hierarchy", source_type: "department", target_type: "stakeholder" },
|
|
@@ -2169,7 +2255,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
2169
2255
|
dashboard_contains_report: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "dashboard", target_type: "report" },
|
|
2170
2256
|
dashboard_contains_experiment_run: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "dashboard", target_type: "experiment_run" },
|
|
2171
2257
|
metric_measures_metric: { forward_verb: "measures", reverse_verb: "measured_by", classification: "cross-domain", source_type: "metric", target_type: "metric" },
|
|
2172
|
-
|
|
2258
|
+
// (UPG-677) metric_measures_metric_cross_domain retired — byte-identical
|
|
2259
|
+
// shadow of metric_measures_metric (the clean key). See
|
|
2260
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2173
2261
|
// `experiment_tests_hypothesis` dropped, superseded by
|
|
2174
2262
|
// the canonical `experiment_run_validates_hypothesis` (causal) introduced
|
|
2175
2263
|
// in v0.2.6. Authors expressing "this experiment tests this hypothesis"
|
|
@@ -2191,7 +2279,11 @@ var UPG_EDGE_CATALOG = {
|
|
|
2191
2279
|
product_area_contains_product_area: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "product_area", target_type: "product_area" },
|
|
2192
2280
|
// decision B: product_area groups features (the natural "Studio area owns 6 features" mental model)
|
|
2193
2281
|
product_area_contains_feature: { forward_verb: "contains", reverse_verb: "belongs_to", classification: "hierarchy", source_type: "product_area", target_type: "feature" },
|
|
2194
|
-
|
|
2282
|
+
// (UPG-677) product_categorised_in_product_area retired — inverse of
|
|
2283
|
+
// product_area_contains_product (the kept containment direction:
|
|
2284
|
+
// product_area → product, matching the UPG parent→child convention). FLAG:
|
|
2285
|
+
// the inverse "product categorised in area" read is preserved by the kept
|
|
2286
|
+
// edge's reverse_verb (belongs_to). See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2195
2287
|
// 8.2 Cross-Product Edges
|
|
2196
2288
|
// direct product-level shorthand edges for market-intelligence shapes.
|
|
2197
2289
|
// These are shortcuts: canonical deep paths go via competitive_analysis and gtm_strategy.
|
|
@@ -2255,7 +2347,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
2255
2347
|
insight_reveals_desired_outcome: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "insight", target_type: "desired_outcome" },
|
|
2256
2348
|
insight_informs_job: { forward_verb: "informs", reverse_verb: "informed_by", classification: "cross-domain", source_type: "insight", target_type: "job" },
|
|
2257
2349
|
insight_characterises_persona: { forward_verb: "characterises", reverse_verb: "characterised_by", classification: "cross-domain", source_type: "insight", target_type: "persona" },
|
|
2258
|
-
|
|
2350
|
+
// (UPG-677) insight_validates_need_cross_domain retired — byte-identical
|
|
2351
|
+
// shadow of insight_validates_need (the clean key). See
|
|
2352
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2259
2353
|
observation_reveals_need: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "observation", target_type: "need" },
|
|
2260
2354
|
observation_characterises_persona: { forward_verb: "characterises", reverse_verb: "characterised_by", classification: "cross-domain", source_type: "observation", target_type: "persona" },
|
|
2261
2355
|
quote_evidences_need: { forward_verb: "evidences", reverse_verb: "evidenced_by", classification: "cross-domain", source_type: "quote", target_type: "need" },
|
|
@@ -2269,7 +2363,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
2269
2363
|
insight_inspires_design_concept: { forward_verb: "inspires", reverse_verb: "inspired_by", classification: "cross-domain", source_type: "insight", target_type: "design_concept" },
|
|
2270
2364
|
observation_yields_insight: { forward_verb: "yields", reverse_verb: "yielded_by", classification: "cross-domain", source_type: "observation", target_type: "insight" },
|
|
2271
2365
|
insight_refines_into_insight: { forward_verb: "refines_into", reverse_verb: "refined_from", classification: "hierarchy", source_type: "insight", target_type: "insight" },
|
|
2272
|
-
|
|
2366
|
+
// (UPG-677) insight_informs_opportunity_cross_domain retired — byte-identical
|
|
2367
|
+
// shadow of insight_informs_opportunity (the clean key). See
|
|
2368
|
+
// UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2273
2369
|
insight_validates_persona: { forward_verb: "validates", reverse_verb: "validated_by", classification: "cross-domain", source_type: "insight", target_type: "persona" },
|
|
2274
2370
|
// Validation-to-Discovery Feedback Loops
|
|
2275
2371
|
learning_validates_opportunity: { forward_verb: "validates", reverse_verb: "validated_by", classification: "cross-domain", source_type: "learning", target_type: "opportunity" },
|
|
@@ -2327,7 +2423,9 @@ var UPG_EDGE_CATALOG = {
|
|
|
2327
2423
|
customer_health_score_composed_of_metric: { forward_verb: "composed_of", reverse_verb: "composes", classification: "cross-domain", source_type: "customer_health_score", target_type: "metric" },
|
|
2328
2424
|
service_level_agreement_measures_metric: { forward_verb: "measures", reverse_verb: "measured_by", classification: "cross-domain", source_type: "service_level_agreement", target_type: "metric" },
|
|
2329
2425
|
// Content
|
|
2330
|
-
|
|
2426
|
+
// (UPG-665) prompt_template_targets_ai_model retired — superseded by the
|
|
2427
|
+
// containment edge ai_model_defines_prompt_template (the model owns its
|
|
2428
|
+
// templates). See UPG_EDGE_MIGRATIONS['0.9.9'].
|
|
2331
2429
|
// Education
|
|
2332
2430
|
education_program_targets_persona: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "education_program", target_type: "persona" },
|
|
2333
2431
|
// Programs
|
|
@@ -2491,13 +2589,13 @@ var UPG_EDGE_CATALOG = {
|
|
|
2491
2589
|
messaging_used_in_launch: { forward_verb: "used_in", reverse_verb: "uses", classification: "cross-domain", source_type: "messaging", target_type: "launch" },
|
|
2492
2590
|
messaging_enables_sales_motion: { forward_verb: "enables", reverse_verb: "enabled_by", classification: "cross-domain", source_type: "messaging", target_type: "sales_motion" },
|
|
2493
2591
|
// Test Card + Learning Card (Strategyzer): canonical validation flow
|
|
2494
|
-
// hypothesis →
|
|
2495
|
-
//
|
|
2496
|
-
//
|
|
2497
|
-
//
|
|
2498
|
-
//
|
|
2499
|
-
//
|
|
2500
|
-
|
|
2592
|
+
// hypothesis → experiment_plan → experiment → experiment_run → evidence →
|
|
2593
|
+
// learning → decision (UPG-664). The "Test Design" card is the
|
|
2594
|
+
// `experiment_plan`; the plan designs the experiment
|
|
2595
|
+
// (`experiment_plan_designs_experiment`), which is executed as run(s). The
|
|
2596
|
+
// former `test_plan_ran_as_experiment_run` bridge was retired when `test_plan`
|
|
2597
|
+
// re-homed to QA (UPG-678) — see UPG_EDGE_MIGRATIONS['0.9.9']. This block keeps
|
|
2598
|
+
// the evidence → learning interpretation and learning → decision commitment.
|
|
2501
2599
|
evidence_interpreted_as_learning: { forward_verb: "interpreted_as", reverse_verb: "interpreted_from", classification: "causal", source_type: "evidence", target_type: "learning" },
|
|
2502
2600
|
learning_informs_decision: { forward_verb: "informs", reverse_verb: "informed_by", classification: "causal", source_type: "learning", target_type: "decision" },
|
|
2503
2601
|
// Opportunity Canvas: Patton's "Assumptions" slot is meant to capture the
|
|
@@ -3223,7 +3321,6 @@ var UPG_VALID_CHILDREN = {
|
|
|
3223
3321
|
"knowledge_base_article",
|
|
3224
3322
|
"brand_asset",
|
|
3225
3323
|
"document",
|
|
3226
|
-
"prompt_template",
|
|
3227
3324
|
"documentation_template",
|
|
3228
3325
|
// Legal
|
|
3229
3326
|
"legal_entity",
|
|
@@ -3256,6 +3353,7 @@ var UPG_VALID_CHILDREN = {
|
|
|
3256
3353
|
"a11y_audit",
|
|
3257
3354
|
"a11y_annotation",
|
|
3258
3355
|
// Quality Assurance
|
|
3356
|
+
"test_plan",
|
|
3259
3357
|
"test_suite",
|
|
3260
3358
|
"qa_session",
|
|
3261
3359
|
"test_coverage_report",
|
|
@@ -3305,7 +3403,10 @@ var UPG_VALID_CHILDREN = {
|
|
|
3305
3403
|
"api_ecosystem",
|
|
3306
3404
|
"developer_portal",
|
|
3307
3405
|
// Portfolio
|
|
3308
|
-
|
|
3406
|
+
// (UPG-677) product no longer lists product_area as a child: the
|
|
3407
|
+
// product↔product_area containment is the single direction
|
|
3408
|
+
// product_area_contains_product (product_area → product). The inverse
|
|
3409
|
+
// product_categorised_in_product_area edge was collapsed.
|
|
3309
3410
|
// Workspace
|
|
3310
3411
|
"workspace"
|
|
3311
3412
|
],
|
|
@@ -3320,22 +3421,27 @@ var UPG_VALID_CHILDREN = {
|
|
|
3320
3421
|
// belief), not the legacy hypothesis type.
|
|
3321
3422
|
solution: ["hypothesis", "prototype", "metric"],
|
|
3322
3423
|
// ── Validation hierarchy ────────────────────────────────────────────────────
|
|
3323
|
-
//
|
|
3324
|
-
//
|
|
3325
|
-
//
|
|
3326
|
-
|
|
3327
|
-
//
|
|
3328
|
-
//
|
|
3329
|
-
|
|
3330
|
-
experiment_plan
|
|
3331
|
-
//
|
|
3332
|
-
//
|
|
3333
|
-
//
|
|
3334
|
-
//
|
|
3335
|
-
|
|
3424
|
+
// (UPG-664) The validation chain is a single-parent line:
|
|
3425
|
+
// hypothesis ▷ experiment_plan ▷ experiment ▷ experiment_run.
|
|
3426
|
+
// hypothesis is canonical (hypothesis_evidence collapsed into evidence;
|
|
3427
|
+
// relationship expressed via hypothesis_has_evidence edge; evidence.direction
|
|
3428
|
+
// carries supports/refutes/neutral semantics). `test_plan` re-homed to the
|
|
3429
|
+
// QA/testing domain (UPG-678), so it is no longer a hypothesis child.
|
|
3430
|
+
hypothesis: ["experiment_plan", "research_plan", "evidence"],
|
|
3431
|
+
// experiment_plan is the canonical validation PLAN (graduated stable,
|
|
3432
|
+
// UPG-664). It designs the experiment it produces; the plan owns the
|
|
3433
|
+
// experiment in the containment line. It also retains experiment_run as a
|
|
3434
|
+
// child for the v0.2.6 split-migration path
|
|
3435
|
+
// (`experiment_plan_ran_as_experiment_run`), where a legacy experiment routes
|
|
3436
|
+
// directly to a plan + run pair.
|
|
3437
|
+
experiment_plan: ["experiment", "experiment_run"],
|
|
3438
|
+
// experiment is the canonical structured test. It owns its run(s) and the
|
|
3439
|
+
// learning/evidence it produces. The optional experiment_run child captures
|
|
3440
|
+
// the multi-run / replication case.
|
|
3441
|
+
experiment: ["experiment_run", "learning", "evidence"],
|
|
3336
3442
|
// experiment_run carries learning/evidence/metric children (run produces
|
|
3337
|
-
// evidence) and self-nests for replications/multi-armed runs
|
|
3338
|
-
//
|
|
3443
|
+
// evidence) and self-nests for replications/multi-armed runs (V9: this is
|
|
3444
|
+
// where self-nesting genuinely lives, not on `experiment`).
|
|
3339
3445
|
experiment_run: ["learning", "evidence", "metric", "experiment_run"],
|
|
3340
3446
|
// ── OKR hierarchy ──────────────────────────────────────────────────────────
|
|
3341
3447
|
objective: ["key_result", "metric"],
|
|
@@ -3346,8 +3452,9 @@ var UPG_VALID_CHILDREN = {
|
|
|
3346
3452
|
strategic_pillar: ["strategic_theme", "capability", "value_stream", "decision"],
|
|
3347
3453
|
// v0.5.4 (UPG-511): objectives are the specific quarterly bets *within* a
|
|
3348
3454
|
// strategic theme. The theme is the multi-quarter focus area; objectives are
|
|
3349
|
-
// subordinate. Pairs with `
|
|
3350
|
-
// catalog (hierarchy, strategic_theme → objective, reverse_verb: rolls_up_to
|
|
3455
|
+
// subordinate. Pairs with `strategic_theme_contains_objective` in the edge
|
|
3456
|
+
// catalog (hierarchy, strategic_theme → objective, reverse_verb: rolls_up_to;
|
|
3457
|
+
// renamed from objective_rolls_up_to_strategic_theme in UPG-676).
|
|
3351
3458
|
strategic_theme: ["initiative", "objective"],
|
|
3352
3459
|
initiative: ["assumption"],
|
|
3353
3460
|
// v0.5.2 (UPG-528): capability decomposes into sub-capabilities (Wardley
|
|
@@ -3527,7 +3634,6 @@ var UPG_VALID_CHILDREN = {
|
|
|
3527
3634
|
"knowledge_base_article",
|
|
3528
3635
|
"brand_asset",
|
|
3529
3636
|
"document",
|
|
3530
|
-
"prompt_template",
|
|
3531
3637
|
"documentation_template"
|
|
3532
3638
|
],
|
|
3533
3639
|
// ── Operations & CS hierarchy ────────────────────────────────────────────────
|
|
@@ -3632,6 +3738,10 @@ var UPG_VALID_CHILDREN = {
|
|
|
3632
3738
|
// a learning_path can include its terminal certification.
|
|
3633
3739
|
learning_path: ["tutorial", "certification"],
|
|
3634
3740
|
// ── Quality Assurance & Testing hierarchy ────────────────────────────────────
|
|
3741
|
+
// (UPG-678) test_plan re-homed validation → QA. It is the QA planning layer:
|
|
3742
|
+
// the verification approach (scope, environments, pass criteria) that the
|
|
3743
|
+
// test suites execute. A test_plan groups the suites that carry it out.
|
|
3744
|
+
test_plan: ["test_suite", "test_environment"],
|
|
3635
3745
|
test_suite: [
|
|
3636
3746
|
"test_case",
|
|
3637
3747
|
"regression_test",
|
|
@@ -3675,8 +3785,11 @@ var UPG_VALID_CHILDREN = {
|
|
|
3675
3785
|
"paywall"
|
|
3676
3786
|
],
|
|
3677
3787
|
// ── AI/ML Operations hierarchy ───────────────────────────────────────────────
|
|
3788
|
+
// (UPG-665) The prompt abstraction is corrected: ai_model → prompt_template →
|
|
3789
|
+
// prompt_version (a model has templates; each template has versions). The
|
|
3790
|
+
// model no longer owns prompt_version directly.
|
|
3678
3791
|
ai_model: [
|
|
3679
|
-
"
|
|
3792
|
+
"prompt_template",
|
|
3680
3793
|
"eval_benchmark",
|
|
3681
3794
|
"ai_cost_tracker",
|
|
3682
3795
|
"hallucination_report",
|
|
@@ -3686,6 +3799,8 @@ var UPG_VALID_CHILDREN = {
|
|
|
3686
3799
|
"ai_dataset",
|
|
3687
3800
|
"ai_trace"
|
|
3688
3801
|
],
|
|
3802
|
+
// prompt_template owns its prompt_versions the way a file owns its commits.
|
|
3803
|
+
prompt_template: ["prompt_version"],
|
|
3689
3804
|
// v0.5.7 (UPG-528 Part 2c): benchmarks define the metric set they measure
|
|
3690
3805
|
// (HELM, MLPerf, BIG-bench all spec a metric list). metric already has many
|
|
3691
3806
|
// hierarchy parents (outcome, objective, key_result, solution, data_source).
|
|
@@ -7552,22 +7667,18 @@ var UPG_PROPERTY_MIGRATIONS = {
|
|
|
7552
7667
|
// graphs typically carry only one of the two; the conflict path is
|
|
7553
7668
|
// theoretical but documented for predictability.
|
|
7554
7669
|
"0.2.13": [
|
|
7555
|
-
// 1.
|
|
7556
|
-
|
|
7557
|
-
|
|
7558
|
-
|
|
7559
|
-
|
|
7560
|
-
|
|
7561
|
-
|
|
7562
|
-
|
|
7563
|
-
|
|
7564
|
-
|
|
7565
|
-
|
|
7566
|
-
|
|
7567
|
-
// UPGProductStage values and need no remap when surfaced inline.
|
|
7568
|
-
},
|
|
7569
|
-
reason: 'lifecycle phase belongs in top-level `status` per UPGBaseNode contract, not in `properties`. Pre-canonical "idea" alias mapped to canonical `concept` (UPGProductStage[0]).'
|
|
7570
|
-
},
|
|
7670
|
+
// 1. (RETIRED in 0.9.10, batch-6 #33) The product `properties.stage` →
|
|
7671
|
+
// top-level `status` lift is superseded by UPG-654/661, which
|
|
7672
|
+
// re-canonicalised a product node's lifecycle stage to
|
|
7673
|
+
// `properties.stage` — a distinct 9-phase `UPGProductStage` axis,
|
|
7674
|
+
// separate from the generic top-level `status` other entities use. The
|
|
7675
|
+
// entire runtime (create_product, get_graph_digest, get_product_context,
|
|
7676
|
+
// completeness, header-sync) reads and writes `properties.stage`, so
|
|
7677
|
+
// lifting it to `status` made a freshly-created product read as
|
|
7678
|
+
// `property_drift` against its own validator (a tool emitting drift its
|
|
7679
|
+
// validator immediately flags). Legacy "idea"-style values are still
|
|
7680
|
+
// normalised on READ by `coerceProductStage`, so retiring the lift loses
|
|
7681
|
+
// no cleanup. Decision: 2026-06-10-product-stage-properties-canonical.md.
|
|
7571
7682
|
// 2. Rename top-level lifecycle_status → status (with value remap).
|
|
7572
7683
|
{
|
|
7573
7684
|
kind: "rename_top_level",
|
|
@@ -7944,6 +8055,69 @@ function getSplitMigrations(fromVersion, toVersion) {
|
|
|
7944
8055
|
return result;
|
|
7945
8056
|
}
|
|
7946
8057
|
var UPG_EDGE_MIGRATIONS = {
|
|
8058
|
+
"0.9.9": [
|
|
8059
|
+
// (since v0.9.9, UPG-664/UPG-678) Validation experiment-model + test_plan
|
|
8060
|
+
// re-home. The validation chain is reshaped to the single-parent line
|
|
8061
|
+
// hypothesis → experiment_plan → experiment → experiment_run, `experiment`
|
|
8062
|
+
// gains its stable hypothesis loop, and `test_plan` re-homes to the QA
|
|
8063
|
+
// domain (its planning role absorbed by `experiment_plan`).
|
|
8064
|
+
//
|
|
8065
|
+
// The plan→experiment containment inverts: the old `experiment_has_plan`
|
|
8066
|
+
// (experiment → experiment_plan, hierarchy) becomes
|
|
8067
|
+
// `experiment_plan_designs_experiment` (experiment_plan → experiment). Flip
|
|
8068
|
+
// swaps endpoints. Endpoint guards reference the post-flip orientation: the
|
|
8069
|
+
// original source (experiment) becomes the new target, the original target
|
|
8070
|
+
// (experiment_plan) becomes the new source.
|
|
8071
|
+
{ kind: "rename", from: "experiment_has_plan", to: "experiment_plan_designs_experiment", flip: true, requires_source_type: "experiment", requires_target_type: "experiment_plan", reason: "Validation experiment-model reshape (UPG-664). The plan owns the experiment it designs; the containment direction inverts from experiment \u2192 experiment_plan to experiment_plan \u2192 experiment. Flip swaps endpoints so the surviving edge reads plan-designs-experiment." },
|
|
8072
|
+
// test_plan re-homed validation → QA (UPG-678). Its two validation-side
|
|
8073
|
+
// edges are dropped: a hypothesis no longer plans via a QA test_plan (it
|
|
8074
|
+
// requires an experiment_plan), and the test_plan → experiment_run ran-as
|
|
8075
|
+
// bridge is superseded by the experiment_plan → experiment flow.
|
|
8076
|
+
{ kind: "drop", from: "hypothesis_planned_via_test_plan", reason: "test_plan re-homed validation \u2192 QA (UPG-678). A hypothesis no longer plans via test_plan; the validation plan is experiment_plan (hypothesis_requires_experiment_plan)." },
|
|
8077
|
+
{ kind: "drop", from: "test_plan_ran_as_experiment_run", reason: "test_plan re-homed validation \u2192 QA (UPG-678). The Strategyzer Test Card flow now runs hypothesis \u2192 experiment_plan \u2192 experiment \u2192 experiment_run; the test_plan \u2192 experiment_run bridge is superseded by experiment_plan_designs_experiment." },
|
|
8078
|
+
// (since v0.9.9, UPG-665) AI prompt-model correction. The prompt abstraction
|
|
8079
|
+
// is inverted to the correct ai_model → prompt_template → prompt_version
|
|
8080
|
+
// containment. The backwards/obsolete edges are dropped, and the
|
|
8081
|
+
// prompt_template → ai_model "targets" relationship is flipped into the new
|
|
8082
|
+
// ai_model → prompt_template ownership.
|
|
8083
|
+
{ kind: "rename", from: "prompt_template_targets_ai_model", to: "ai_model_defines_prompt_template", flip: true, requires_source_type: "prompt_template", requires_target_type: "ai_model", reason: 'AI prompt-model correction (UPG-665). The model owns its templates; the prompt_template \u2192 ai_model "targets" edge becomes the ai_model \u2192 prompt_template ownership edge. Flip swaps endpoints so the surviving edge reads model-defines-template.' },
|
|
8084
|
+
{ kind: "drop", from: "prompt_version_evolves_prompt_template", reason: "AI prompt-model correction (UPG-665). The backwards prompt_version \u2192 prompt_template edge is retired; prompt_template now contains its versions (prompt_template_contains_prompt_version)." },
|
|
8085
|
+
{ kind: "drop", from: "ai_model_prompted_via_prompt_version", reason: "AI prompt-model correction (UPG-665). The model no longer owns prompt_version directly; the chain is ai_model \u2192 prompt_template \u2192 prompt_version." },
|
|
8086
|
+
{ kind: "drop", from: "product_prompted_via_prompt_template", reason: "AI prompt-model correction (UPG-665). prompt_template re-parented product \u2192 ai_model (ai_model_defines_prompt_template); the product-level containment is removed." },
|
|
8087
|
+
{ kind: "drop", from: "content_calendar_schedules_prompt_template", reason: "AI prompt-model correction (UPG-665). prompt_template re-homed into the ai_model containment tree; it is an AI artefact, not a content-calendar-scheduled item." },
|
|
8088
|
+
// (since v0.9.9, UPG-676) Strategic-theme containment edge rename. The
|
|
8089
|
+
// malformed `objective_rolls_up_to_strategic_theme` (key read object-first
|
|
8090
|
+
// while source_type was strategic_theme; forward_verb was the malformed
|
|
8091
|
+
// `contains_objective`) is renamed to the clean source-first
|
|
8092
|
+
// `strategic_theme_contains_objective`. Endpoints unchanged
|
|
8093
|
+
// (strategic_theme → objective); only the key and forward verb change.
|
|
8094
|
+
{ kind: "rename", from: "objective_rolls_up_to_strategic_theme", to: "strategic_theme_contains_objective", requires_source_type: "strategic_theme", requires_target_type: "objective", reason: "Strategic-theme containment edge rename (UPG-676). The key now reads source-first and the forward verb is the clean `contains` (was the malformed `contains_objective`). Endpoints unchanged (strategic_theme \u2192 objective); satisfies the F2 prefix gate." },
|
|
8095
|
+
// (since v0.9.9, UPG-677) Duplicate / shadow edge collapse. Each retired key
|
|
8096
|
+
// is dual-read to the surviving canonical key. Tier 1 = byte-identical
|
|
8097
|
+
// shadows; Tier 2 = tense/suffix twins; Tier 3 = near-synonyms collapsed per
|
|
8098
|
+
// Captain's lean. Inverse pairs flip the direction onto the kept containment
|
|
8099
|
+
// edge. Collapsing these lowers the edge-duplicate gate collision bound.
|
|
8100
|
+
// ── Tier 1: byte-identical shadows ──
|
|
8101
|
+
{ kind: "rename", from: "insight_informs_opportunity_cross_domain", to: "insight_informs_opportunity", requires_source_type: "insight", requires_target_type: "opportunity", reason: "Duplicate collapse (UPG-677). Byte-identical shadow of insight_informs_opportunity; the suffixed twin never resolved." },
|
|
8102
|
+
{ kind: "rename", from: "product_experiences_incident_hierarchy", to: "product_experiences_incident", requires_source_type: "product", requires_target_type: "incident", reason: "Duplicate collapse (UPG-677). Byte-identical shadow of product_experiences_incident; the suffixed twin never resolved." },
|
|
8103
|
+
{ kind: "rename", from: "value_proposition_targets_persona_cross_domain", to: "value_proposition_targets_persona", requires_source_type: "value_proposition", requires_target_type: "persona", reason: "Duplicate collapse (UPG-677). Byte-identical shadow of value_proposition_targets_persona; the suffixed twin never resolved." },
|
|
8104
|
+
{ kind: "rename", from: "metric_measures_metric_cross_domain", to: "metric_measures_metric", requires_source_type: "metric", requires_target_type: "metric", reason: "Duplicate collapse (UPG-677). Byte-identical shadow of metric_measures_metric; the suffixed twin never resolved." },
|
|
8105
|
+
{ kind: "rename", from: "insight_validates_need_cross_domain", to: "insight_validates_need", requires_source_type: "insight", requires_target_type: "need", reason: "Duplicate collapse (UPG-677). Byte-identical shadow of insight_validates_need; the suffixed twin never resolved." },
|
|
8106
|
+
// ── Tier 2: tense / suffix twins ──
|
|
8107
|
+
{ kind: "rename", from: "metric_decomposed_into_metric", to: "metric_decomposes_into_metric", requires_source_type: "metric", requires_target_type: "metric", reason: "Duplicate collapse (UPG-677). Tense-twin of the active-voice metric_decomposes_into_metric." },
|
|
8108
|
+
{ kind: "rename", from: "product_decided_via_decision_hierarchy", to: "product_decided_via_decision", requires_source_type: "product", requires_target_type: "decision", reason: "Duplicate collapse (UPG-677). Suffix-twin of product_decided_via_decision." },
|
|
8109
|
+
{ kind: "rename", from: "support_ticket_reveals_need_cross_domain", to: "support_ticket_reveals_need", requires_source_type: "support_ticket", requires_target_type: "need", reason: "Duplicate collapse (UPG-677). Near-duplicate of support_ticket_reveals_need (whose reverse_verb is normalised to revealed_by)." },
|
|
8110
|
+
// ── Tier 3: near-synonyms (Captain's lean = collapse) ──
|
|
8111
|
+
{ kind: "rename", from: "outcome_tracked_by_metric", to: "outcome_measured_by_metric", requires_source_type: "outcome", requires_target_type: "metric", reason: "Duplicate collapse (UPG-677). Near-synonym of outcome_measured_by_metric (keep measured_by, drop tracked_by)." },
|
|
8112
|
+
{ kind: "rename", from: "key_result_tracked_by_metric", to: "key_result_quantified_by_metric", requires_source_type: "key_result", requires_target_type: "metric", reason: "Duplicate collapse (UPG-677). Near-synonym of key_result_quantified_by_metric (keep quantified_by, drop tracked_by)." },
|
|
8113
|
+
{ kind: "rename", from: "business_model_reaches_via_distribution_channel", to: "business_model_distributes_via_distribution_channel", requires_source_type: "business_model", requires_target_type: "distribution_channel", reason: "Duplicate collapse (UPG-677). Near-synonym of business_model_distributes_via_distribution_channel (the Business Model Canvas Channels verb)." },
|
|
8114
|
+
// ── Inverse pairs: flip onto the kept containment edge ──
|
|
8115
|
+
// Flip guards reference the PRE-flip (original-edge) endpoints: the original
|
|
8116
|
+
// source becomes the new target after flip, so requires_source_type matches
|
|
8117
|
+
// the new edge's target_type and requires_target_type matches its source_type.
|
|
8118
|
+
{ kind: "rename", from: "product_categorised_in_product_area", to: "product_area_contains_product", flip: true, requires_source_type: "product", requires_target_type: "product_area", reason: 'Duplicate collapse (UPG-677). Inverse of the containment edge product_area_contains_product (product_area \u2192 product). Flip swaps endpoints; the "categorised in" read survives as the reverse_verb belongs_to.' },
|
|
8119
|
+
{ kind: "rename", from: "changelog_documents_release", to: "release_documented_in_changelog", flip: true, requires_source_type: "changelog", requires_target_type: "release", reason: 'Duplicate collapse (UPG-677). Inverse of the containment edge release_documented_in_changelog (release \u2192 changelog, matching hierarchy release: [changelog]). Flip swaps endpoints; the "changelog documents release" read survives as the reverse_verb documents.' }
|
|
8120
|
+
],
|
|
7947
8121
|
"0.9.2": [
|
|
7948
8122
|
// (since v0.9.2, UPG-663) Journey-model disambiguation. A journey_phase
|
|
7949
8123
|
// is a temporal BAND over the journey's single step timeline, not a
|
|
@@ -9562,6 +9736,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
9562
9736
|
// CustomerJourneyStageProperties: Customer journey stage.
|
|
9563
9737
|
customer_journey_stage: {
|
|
9564
9738
|
stage_type: { type: "string", enum: ["awareness", "acquisition", "activation", "retention", "revenue", "referral"], description: "Which pirate metric (AAARRR) this stage maps to" },
|
|
9739
|
+
stage_order: { type: "number", description: "Display order along the lifecycle timeline (0-indexed). The `*_order` convention shared with `journey_phase.phase_order` and `journey_step.step_order` (UPG-675 / CS-8), so two same-`stage_type` stages are orderable." },
|
|
9565
9740
|
avg_duration: { type: "string", description: "Average time a customer spends in this stage" },
|
|
9566
9741
|
conversion_rate: { type: "number", description: "Percentage of customers who advance to the next stage" }
|
|
9567
9742
|
},
|
|
@@ -9953,7 +10128,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
9953
10128
|
observed_at: { type: "string", description: "ISO date observed." },
|
|
9954
10129
|
source: { type: "string", description: "Free-text provenance note" }
|
|
9955
10130
|
},
|
|
9956
|
-
// ExperimentProperties: A structured
|
|
10131
|
+
// ExperimentProperties: A structured test designed to validate a hypothesis. The canonical unit of
|
|
9957
10132
|
experiment: {
|
|
9958
10133
|
method: { type: "string", description: 'Experimental method (e.g. "A/B test", "usability study", "smoke test")' },
|
|
9959
10134
|
start_date: { type: "string", description: "ISO start date" },
|
|
@@ -9963,10 +10138,11 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
9963
10138
|
expected_lift_unit: { type: "string", enum: ["percentage", "absolute", "ratio"], description: "Unit of `expected_lift`" },
|
|
9964
10139
|
actual_lift: { type: "number", description: "Observed change in the primary metric" }
|
|
9965
10140
|
},
|
|
9966
|
-
// ExperimentPlanProperties:
|
|
10141
|
+
// ExperimentPlanProperties: The validation PLAN: the design for a structured test of a hypothesis
|
|
9967
10142
|
experiment_plan: {
|
|
9968
10143
|
method: { type: "string", enum: ["a_b_test", "multivariate", "qual_interview", "prototype_test", "fake_door", "wizard_of_oz", "longitudinal"], description: "Experimental method. Drives renderer and analysis tooling." },
|
|
9969
10144
|
success_criteria: { type: "string", description: 'Plain-English description of "passing"' },
|
|
10145
|
+
sample_size: { type: "number", description: "Targeted participants or observations for the planned test. Absorbed from `test_plan` (UPG-678) when it re-homed to QA; the planning sample size now lives on the validation plan." },
|
|
9970
10146
|
projected_reach: {
|
|
9971
10147
|
type: "assessment",
|
|
9972
10148
|
scale_id: "reach_5",
|
|
@@ -10502,7 +10678,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10502
10678
|
// JourneyStepProperties: Single step within a user journey. A user-moment on the journey's single
|
|
10503
10679
|
journey_step: {
|
|
10504
10680
|
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." },
|
|
10505
|
-
touchpoint: { type: "string", description: "
|
|
10681
|
+
touchpoint: { type: "string", description: "@deprecated since v0.9.9 (UPG-675). Touchpoints are modelled in two places, neither of which is this string: the `touchpoint` *entity* is the cross-channel customer-success layer (`touchpoint_occurs_in_journey_step`), and `journey_action` is the in-product blueprint layer (the finest band of a `journey_step`). Use one of those rather than a free-text string here. Removed in a future major." },
|
|
10506
10682
|
channel: { type: "string", description: 'Channel (e.g. "web", "email", "in-store")' },
|
|
10507
10683
|
emotion_score: {
|
|
10508
10684
|
type: "assessment",
|
|
@@ -11772,12 +11948,13 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
11772
11948
|
env_status: { type: "string", enum: ["available", "in_use", "maintenance", "unavailable"], description: "Current availability status of the environment" },
|
|
11773
11949
|
config: { type: "string", description: "Configuration details (e.g. OS, browser version, database seed)" }
|
|
11774
11950
|
},
|
|
11775
|
-
// TestPlanProperties:
|
|
11951
|
+
// TestPlanProperties: Test plan: the QA verification procedure for a product or release.
|
|
11776
11952
|
test_plan: {
|
|
11777
|
-
|
|
11778
|
-
|
|
11779
|
-
|
|
11780
|
-
|
|
11953
|
+
test_scope: { type: "string", description: 'What the plan covers (e.g. "checkout flow", "auth module", "release 2.4").' },
|
|
11954
|
+
plan_type: { type: "string", enum: ["release", "regression", "integration", "acceptance", "smoke", "exploratory"], description: "Kind of verification effort this plan governs." },
|
|
11955
|
+
environments: { type: "object", description: "Environments the plan exercises (mirrors `TestEnvironmentProperties.env_type`)." },
|
|
11956
|
+
entry_criteria: { type: "string", description: "Conditions that must hold before execution may begin." },
|
|
11957
|
+
pass_criteria: { type: "string", description: "Exit / pass criteria determining whether the plan succeeds." }
|
|
11781
11958
|
},
|
|
11782
11959
|
// TestResultProperties: Single test execution result.
|
|
11783
11960
|
test_result: {
|
|
@@ -11843,7 +12020,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
11843
12020
|
},
|
|
11844
12021
|
// TouchpointProperties: Customer touchpoint.
|
|
11845
12022
|
touchpoint: {
|
|
11846
|
-
touchpoint_channel: { type: "string",
|
|
12023
|
+
touchpoint_channel: { type: "string", enum: ["in_app", "email", "phone", "chat", "sms", "in_person", "mail"], description: "Medium (modality) of the interaction: how it physically happens. Distinct from a go-to-market *channel* (`marketing_channel`/`acquisition_channel`/ `distribution_channel`), which are market routes, not interaction media. (UPG-679)" },
|
|
11847
12024
|
touchpoint_type: { type: "string", enum: ["reactive", "proactive", "automated"], description: "Whether the touchpoint is initiated by the customer, CSM, or system" },
|
|
11848
12025
|
satisfaction_score: { type: "number", description: "Customer satisfaction score for this touchpoint" }
|
|
11849
12026
|
},
|
|
@@ -11896,7 +12073,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
11896
12073
|
// UserJourneyProperties: User journey map.
|
|
11897
12074
|
user_journey: {
|
|
11898
12075
|
scope: { type: "string", description: 'Scope (e.g. "end-to-end onboarding")' },
|
|
11899
|
-
journey_type: { type: "string", enum: ["current_state", "future_state", "day_in_the_life"
|
|
12076
|
+
journey_type: { type: "string", enum: ["current_state", "future_state", "day_in_the_life"], description: "Maps current or future state" },
|
|
11900
12077
|
scenario: { type: "string", description: "Scenario context" }
|
|
11901
12078
|
},
|
|
11902
12079
|
// UserStoryProperties: "As X, I want Y so Z" templated promise on a user story (UCS pattern P5).
|
|
@@ -17966,9 +18143,10 @@ var PRIORITY_LABELS = [
|
|
|
17966
18143
|
{
|
|
17967
18144
|
id: "experiment",
|
|
17968
18145
|
canonical_label: "Experiment",
|
|
18146
|
+
// V6 (UPG-664): dropped 'test' (too generic; collides) and 'validation'
|
|
18147
|
+
// (the domain name). The deprecated growth/pricing/ab experiment types
|
|
18148
|
+
// redirect to `experiment` (V2), so their labels stay here.
|
|
17969
18149
|
alt_labels: [
|
|
17970
|
-
"test",
|
|
17971
|
-
"validation",
|
|
17972
18150
|
"ab test",
|
|
17973
18151
|
"a/b test",
|
|
17974
18152
|
"split test",
|
|
@@ -18424,8 +18602,8 @@ var STANDARD_LABELS = {
|
|
|
18424
18602
|
design_sprint: { alt_labels: ["sprint", "gv sprint", "google ventures sprint"] },
|
|
18425
18603
|
// Validation layer
|
|
18426
18604
|
learning: { alt_labels: ["validated learning", "lesson learned", "takeaway"] },
|
|
18427
|
-
//
|
|
18428
|
-
|
|
18605
|
+
// test_plan re-homed validation → QA (UPG-678); its label entry now lives in
|
|
18606
|
+
// the Quality Assurance & Testing layer below.
|
|
18429
18607
|
research_plan: { alt_labels: ["study plan", "research brief"] },
|
|
18430
18608
|
evidence: { alt_labels: ["proof", "supporting data", "signal"] },
|
|
18431
18609
|
variant: { alt_labels: ["test variant", "experiment arm", "variation"] },
|
|
@@ -18679,6 +18857,10 @@ var STANDARD_LABELS = {
|
|
|
18679
18857
|
help_video: { alt_labels: ["tutorial video", "screencast", "how-to video"] },
|
|
18680
18858
|
learning_path: { alt_labels: ["curriculum", "course track", "learning journey"] },
|
|
18681
18859
|
// Quality Assurance & Testing layer
|
|
18860
|
+
// test_plan re-homed validation → QA (UPG-678): QA-shaped labels only.
|
|
18861
|
+
// 'validation plan' and 'experiment plan' stripped — those belong to the
|
|
18862
|
+
// validation-side `experiment_plan` type.
|
|
18863
|
+
test_plan: { alt_labels: ["test strategy", "qa plan", "master test plan"] },
|
|
18682
18864
|
test_suite: { alt_labels: ["test collection", "test group"] },
|
|
18683
18865
|
test_case: { alt_labels: ["test", "test scenario", "verification step"] },
|
|
18684
18866
|
qa_session: { alt_labels: ["testing session", "exploratory test", "qa round"] },
|
|
@@ -19050,11 +19232,13 @@ var DISCOVERY_RESEARCH_VALIDATION_PLAYBOOK = {
|
|
|
19050
19232
|
seqStep(
|
|
19051
19233
|
8,
|
|
19052
19234
|
"Test",
|
|
19053
|
-
// DT-PB-1: was `experiment` — which
|
|
19054
|
-
// hypothesis
|
|
19055
|
-
//
|
|
19056
|
-
//
|
|
19057
|
-
|
|
19235
|
+
// DT-PB-1: was `experiment` — which resolved to NO canonical edge with
|
|
19236
|
+
// hypothesis, forcing an orphan. `experiment_run` is the hypothesis-linked
|
|
19237
|
+
// test unit (experiment_run_validates_hypothesis, experiment_run_yields_evidence).
|
|
19238
|
+
// (UPG-664) `test_plan` re-homed to QA (UPG-678); the validation plan is
|
|
19239
|
+
// `experiment_plan`, which designs the experiment
|
|
19240
|
+
// (experiment_plan_designs_experiment) and runs as experiment_run(s).
|
|
19241
|
+
["experiment_run", "experiment_plan", "evidence"],
|
|
19058
19242
|
"Validate with targeted experiment runs. Close the loop between research and action."
|
|
19059
19243
|
)
|
|
19060
19244
|
]
|
|
@@ -20287,19 +20471,23 @@ var UPG_DOMAIN_RINGS = [
|
|
|
20287
20471
|
id: "define",
|
|
20288
20472
|
label: "Define",
|
|
20289
20473
|
description: "What are we building?",
|
|
20290
|
-
|
|
20474
|
+
// `business_model` lives in the `define` ring (foundational "what are we
|
|
20475
|
+
// building & how it sustains"), not in `grow`. This is an intentional
|
|
20476
|
+
// ring-vs-region divergence: UPG_REGIONS still groups business_model under
|
|
20477
|
+
// `business_gtm_growth` (region membership is a separately-tracked decision).
|
|
20478
|
+
domain_ids: ["strategy", "product_spec", "business_model", "ux_design", "design_system", "brand", "legal"]
|
|
20291
20479
|
},
|
|
20292
20480
|
{
|
|
20293
20481
|
id: "build",
|
|
20294
20482
|
label: "Build",
|
|
20295
20483
|
description: "How do we construct it?",
|
|
20296
|
-
domain_ids: ["engineering", "
|
|
20484
|
+
domain_ids: ["engineering", "ai", "automation", "data_analytics", "testing", "devops", "security", "accessibility"]
|
|
20297
20485
|
},
|
|
20298
20486
|
{
|
|
20299
20487
|
id: "grow",
|
|
20300
20488
|
label: "Grow",
|
|
20301
20489
|
description: "How do we make money?",
|
|
20302
|
-
domain_ids: ["
|
|
20490
|
+
domain_ids: ["pricing", "go_to_market", "sales", "marketing", "growth"]
|
|
20303
20491
|
},
|
|
20304
20492
|
{
|
|
20305
20493
|
id: "operate",
|
|
@@ -20311,9 +20499,27 @@ var UPG_DOMAIN_RINGS = [
|
|
|
20311
20499
|
id: "extend",
|
|
20312
20500
|
label: "Extend",
|
|
20313
20501
|
description: "How do we scale?",
|
|
20314
|
-
domain_ids: ["team_org", "program_mgmt", "
|
|
20502
|
+
domain_ids: ["team_org", "program_mgmt", "ecosystem", "localisation", "compliance"]
|
|
20315
20503
|
}
|
|
20316
20504
|
];
|
|
20505
|
+
function assertRingsPartitionDomains() {
|
|
20506
|
+
const ringDomainIds = UPG_DOMAIN_RINGS.flatMap((r) => [...r.domain_ids]);
|
|
20507
|
+
const canonical = new Set(UPG_DOMAINS.map((d) => d.id));
|
|
20508
|
+
const ringSet = new Set(ringDomainIds);
|
|
20509
|
+
const duplicates = ringDomainIds.filter((id, i) => ringDomainIds.indexOf(id) !== i);
|
|
20510
|
+
const unknown = [...ringSet].filter((id) => !canonical.has(id));
|
|
20511
|
+
const unassigned = [...canonical].filter((id) => !ringSet.has(id));
|
|
20512
|
+
if (duplicates.length || unknown.length || unassigned.length) {
|
|
20513
|
+
const parts = [];
|
|
20514
|
+
if (unassigned.length) parts.push(`domains in no ring: [${unassigned.join(", ")}]`);
|
|
20515
|
+
if (unknown.length) parts.push(`ring domains not in UPG_DOMAINS: [${unknown.join(", ")}]`);
|
|
20516
|
+
if (duplicates.length) parts.push(`domains in multiple rings: [${[...new Set(duplicates)].join(", ")}]`);
|
|
20517
|
+
throw new Error(
|
|
20518
|
+
`UPG_DOMAIN_RINGS must partition UPG_DOMAINS exactly: ${parts.join("; ")}. Slot every domain into exactly one ring in domain-rings.ts.`
|
|
20519
|
+
);
|
|
20520
|
+
}
|
|
20521
|
+
}
|
|
20522
|
+
assertRingsPartitionDomains();
|
|
20317
20523
|
function getRingForDomain(domainId) {
|
|
20318
20524
|
return UPG_DOMAIN_RINGS.find((ring) => ring.domain_ids.includes(domainId));
|
|
20319
20525
|
}
|
|
@@ -20321,6 +20527,9 @@ function getDomainsInRing(ringId) {
|
|
|
20321
20527
|
const ring = UPG_DOMAIN_RINGS.find((r) => r.id === ringId);
|
|
20322
20528
|
return ring ? [...ring.domain_ids] : [];
|
|
20323
20529
|
}
|
|
20530
|
+
function ringOrderedDomainIds() {
|
|
20531
|
+
return UPG_DOMAIN_RINGS.flatMap((ring) => [...ring.domain_ids]);
|
|
20532
|
+
}
|
|
20324
20533
|
|
|
20325
20534
|
// src/intelligence/domain-guides.ts
|
|
20326
20535
|
var USER_GUIDE = {
|
|
@@ -20430,19 +20639,18 @@ var DISCOVERY_GUIDE = {
|
|
|
20430
20639
|
var VALIDATION_GUIDE = {
|
|
20431
20640
|
domain_id: "validation",
|
|
20432
20641
|
anchor_entity: "hypothesis",
|
|
20433
|
-
// creation_sequence covers every entity registered to the
|
|
20434
|
-
//
|
|
20435
|
-
//
|
|
20436
|
-
//
|
|
20437
|
-
//
|
|
20438
|
-
|
|
20439
|
-
creation_sequence: ["hypothesis", "experiment_plan", "experiment_run", "test_plan", "evidence", "learning", "research_plan", "experiment"],
|
|
20642
|
+
// (UPG-664) creation_sequence covers every entity registered to the
|
|
20643
|
+
// `validation` domain along the canonical chain hypothesis → experiment_plan
|
|
20644
|
+
// → experiment → experiment_run. `experiment` is the canonical structured
|
|
20645
|
+
// test; experiment_run is its optional replication child. `test_plan`
|
|
20646
|
+
// re-homed to the QA/testing domain (UPG-678).
|
|
20647
|
+
creation_sequence: ["hypothesis", "experiment_plan", "experiment", "experiment_run", "evidence", "learning", "research_plan"],
|
|
20440
20648
|
patterns: [
|
|
20441
20649
|
{
|
|
20442
20650
|
name: "Hypothesis Testing Loop",
|
|
20443
|
-
description: "
|
|
20444
|
-
entity_types: ["hypothesis", "experiment_plan", "experiment_run", "evidence", "learning"],
|
|
20445
|
-
edge_chain: ["hypothesis_requires_experiment_plan", "
|
|
20651
|
+
description: "A hypothesis requires a plan (the experiment design), the plan designs an experiment (the structured test), the experiment is executed as run(s) that produce evidence and learnings, and learnings update the hypothesis",
|
|
20652
|
+
entity_types: ["hypothesis", "experiment_plan", "experiment", "experiment_run", "evidence", "learning"],
|
|
20653
|
+
edge_chain: ["hypothesis_requires_experiment_plan", "experiment_plan_designs_experiment", "experiment_executed_as_experiment_run", "experiment_run_yields_evidence", "experiment_run_produces_learning", "learning_updates_hypothesis"]
|
|
20446
20654
|
}
|
|
20447
20655
|
],
|
|
20448
20656
|
required_bridges: [
|
|
@@ -20560,7 +20768,8 @@ var UX_DESIGN_GUIDE = {
|
|
|
20560
20768
|
anti_patterns: [
|
|
20561
20769
|
{ description: "Screens without journeys: isolated screens miss the experience context" },
|
|
20562
20770
|
{ description: "Prototypes without testing: if nobody tests the prototype, it is just art" },
|
|
20563
|
-
{ description: "Design questions left open: exploration status should progress to resolved or parked" }
|
|
20771
|
+
{ description: "Design questions left open: exploration status should progress to resolved or parked" },
|
|
20772
|
+
{ description: "Touchpoints stuffed in the deprecated journey_step.touchpoint string (UPG-675). Touchpoints belong in one of two layers: journey_action is the in-product blueprint layer (the finest band of a journey_step), and the touchpoint entity is the cross-channel customer-success layer (touchpoint_occurs_in_journey_step). Pick the layer; do not duplicate the touch as a free-text string." }
|
|
20564
20773
|
]
|
|
20565
20774
|
};
|
|
20566
20775
|
var DESIGN_SYSTEM_GUIDE = {
|
|
@@ -20703,7 +20912,9 @@ var DEVOPS_GUIDE = {
|
|
|
20703
20912
|
var TESTING_GUIDE = {
|
|
20704
20913
|
domain_id: "testing",
|
|
20705
20914
|
anchor_entity: "test_suite",
|
|
20706
|
-
|
|
20915
|
+
// (UPG-678) test_plan re-homed validation → QA: the verification-approach
|
|
20916
|
+
// plan that the suites execute. Listed first as the QA planning layer.
|
|
20917
|
+
creation_sequence: ["test_plan", "test_suite", "test_case", "qa_session", "regression_test", "test_coverage_report", "test_environment", "test_result"],
|
|
20707
20918
|
patterns: [
|
|
20708
20919
|
{
|
|
20709
20920
|
name: "Test Pyramid",
|
|
@@ -20800,7 +21011,7 @@ var AI_GUIDE = {
|
|
|
20800
21011
|
}
|
|
20801
21012
|
],
|
|
20802
21013
|
required_bridges: [
|
|
20803
|
-
{ edge_type: "
|
|
21014
|
+
{ edge_type: "ai_dataset_sourced_from_data_source", target_domain: "data_analytics", when: "AI datasets should trace provenance to the data sources they draw from" },
|
|
20804
21015
|
{ edge_type: "ai_guardrail_enforces_security_policy", target_domain: "security", when: "AI guardrails should map to the security policies that constrain them" }
|
|
20805
21016
|
],
|
|
20806
21017
|
anti_patterns: [
|
|
@@ -20991,7 +21202,8 @@ var CUSTOMER_SUCCESS_GUIDE = {
|
|
|
20991
21202
|
anti_patterns: [
|
|
20992
21203
|
{ description: "Health scores without components: define which metrics compose the score" },
|
|
20993
21204
|
{ description: "Playbooks without triggers: specify what conditions activate each playbook" },
|
|
20994
|
-
{ description: "Churn reasons without analysis: understand patterns, not just individual cases" }
|
|
21205
|
+
{ description: "Churn reasons without analysis: understand patterns, not just individual cases" },
|
|
21206
|
+
{ description: "Conflating the two journey models (UPG-675). customer_journey_stage models the post-sale AARRR lifecycle (a customer-success timeline; use stage_order to sequence stages); journey_phase models in-product experience phases of a single user_journey. They are different lenses, not duplicates. Likewise, the touchpoint entity is the cross-channel customer-success layer, distinct from the in-product journey_action." }
|
|
20995
21207
|
]
|
|
20996
21208
|
};
|
|
20997
21209
|
var CONTENT_GUIDE = {
|
|
@@ -24389,9 +24601,7 @@ var UPG_REGIONS = [
|
|
|
24389
24601
|
"objective_achieved_through_key_result",
|
|
24390
24602
|
"objective_measured_by_metric",
|
|
24391
24603
|
"key_result_quantified_by_metric",
|
|
24392
|
-
"key_result_tracked_by_metric",
|
|
24393
24604
|
"outcome_measured_by_metric",
|
|
24394
|
-
"outcome_tracked_by_metric",
|
|
24395
24605
|
"metric_decomposes_into_metric",
|
|
24396
24606
|
"metric_guards_metric",
|
|
24397
24607
|
"metric_drives_metric"
|
|
@@ -24645,8 +24855,7 @@ var UPG_REGIONS = [
|
|
|
24645
24855
|
},
|
|
24646
24856
|
{
|
|
24647
24857
|
type: "experiment",
|
|
24648
|
-
role: "hub"
|
|
24649
|
-
notes: "self-nesting"
|
|
24858
|
+
role: "hub"
|
|
24650
24859
|
},
|
|
24651
24860
|
{
|
|
24652
24861
|
type: "experiment_plan",
|
|
@@ -24654,7 +24863,8 @@ var UPG_REGIONS = [
|
|
|
24654
24863
|
},
|
|
24655
24864
|
{
|
|
24656
24865
|
type: "experiment_run",
|
|
24657
|
-
role: "container"
|
|
24866
|
+
role: "container",
|
|
24867
|
+
notes: "self-nesting"
|
|
24658
24868
|
},
|
|
24659
24869
|
{
|
|
24660
24870
|
type: "learning",
|
|
@@ -24664,10 +24874,6 @@ var UPG_REGIONS = [
|
|
|
24664
24874
|
type: "evidence",
|
|
24665
24875
|
role: "leaf"
|
|
24666
24876
|
},
|
|
24667
|
-
{
|
|
24668
|
-
type: "test_plan",
|
|
24669
|
-
role: "leaf"
|
|
24670
|
-
},
|
|
24671
24877
|
{
|
|
24672
24878
|
type: "research_plan",
|
|
24673
24879
|
role: "leaf"
|
|
@@ -24759,7 +24965,7 @@ var UPG_REGIONS = [
|
|
|
24759
24965
|
},
|
|
24760
24966
|
{
|
|
24761
24967
|
direction: "export",
|
|
24762
|
-
edge_id: "
|
|
24968
|
+
edge_id: "insight_informs_opportunity",
|
|
24763
24969
|
crosses_into: "discovery_research_validation"
|
|
24764
24970
|
},
|
|
24765
24971
|
{
|
|
@@ -25443,7 +25649,7 @@ var UPG_REGIONS = [
|
|
|
25443
25649
|
},
|
|
25444
25650
|
{
|
|
25445
25651
|
type: "prompt_template",
|
|
25446
|
-
role: "
|
|
25652
|
+
role: "container"
|
|
25447
25653
|
},
|
|
25448
25654
|
{
|
|
25449
25655
|
type: "prompt_version",
|
|
@@ -25875,7 +26081,7 @@ var UPG_REGIONS = [
|
|
|
25875
26081
|
"business_model_earns_via_revenue_stream",
|
|
25876
26082
|
"business_model_costs_via_cost_structure",
|
|
25877
26083
|
"business_model_measured_by_unit_economics",
|
|
25878
|
-
"
|
|
26084
|
+
"business_model_distributes_via_distribution_channel",
|
|
25879
26085
|
"business_model_maintains_customer_relationship",
|
|
25880
26086
|
"business_model_requires_key_resource",
|
|
25881
26087
|
"business_model_performs_key_activity",
|
|
@@ -26044,11 +26250,6 @@ var UPG_REGIONS = [
|
|
|
26044
26250
|
edge_id: "key_result_quantified_by_metric",
|
|
26045
26251
|
crosses_into: "strategy_outcomes"
|
|
26046
26252
|
},
|
|
26047
|
-
{
|
|
26048
|
-
direction: "import",
|
|
26049
|
-
edge_id: "key_result_tracked_by_metric",
|
|
26050
|
-
crosses_into: "strategy_outcomes"
|
|
26051
|
-
},
|
|
26052
26253
|
{
|
|
26053
26254
|
direction: "import",
|
|
26054
26255
|
edge_id: "revenue_stream_measured_by_metric_cross_domain",
|
|
@@ -26160,6 +26361,10 @@ var UPG_REGIONS = [
|
|
|
26160
26361
|
type: "infrastructure_component",
|
|
26161
26362
|
role: "container"
|
|
26162
26363
|
},
|
|
26364
|
+
{
|
|
26365
|
+
type: "test_plan",
|
|
26366
|
+
role: "container"
|
|
26367
|
+
},
|
|
26163
26368
|
{
|
|
26164
26369
|
type: "test_suite",
|
|
26165
26370
|
role: "container"
|
|
@@ -26441,7 +26646,7 @@ var UPG_REGIONS = [
|
|
|
26441
26646
|
boundary_edges: [
|
|
26442
26647
|
{
|
|
26443
26648
|
direction: "import",
|
|
26444
|
-
edge_id: "
|
|
26649
|
+
edge_id: "product_experiences_incident",
|
|
26445
26650
|
crosses_into: "product_delivery"
|
|
26446
26651
|
},
|
|
26447
26652
|
{
|
|
@@ -26991,7 +27196,7 @@ function isCanonical(text) {
|
|
|
26991
27196
|
}
|
|
26992
27197
|
|
|
26993
27198
|
// src/index.ts
|
|
26994
|
-
var UPG_VERSION = "0.9.
|
|
27199
|
+
var UPG_VERSION = "0.9.10";
|
|
26995
27200
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
26996
27201
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
26997
27202
|
var UPG_TYPES = getTypes();
|
|
@@ -27218,6 +27423,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
|
|
|
27218
27423
|
resolveEntityType,
|
|
27219
27424
|
resolveLabel,
|
|
27220
27425
|
resolveSlugCollision,
|
|
27426
|
+
ringOrderedDomainIds,
|
|
27221
27427
|
rotateSlug,
|
|
27222
27428
|
serializeCanonical,
|
|
27223
27429
|
validateProductStageStrict,
|