@unified-product-graph/core 0.9.5 → 0.9.7
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 +40 -0
- package/dist/index.cjs +836 -74
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +281 -4
- package/dist/index.d.ts +281 -4
- package/dist/index.js +835 -74
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
PRODUCT_DELIVERY_PLAYBOOK: () => PRODUCT_DELIVERY_PLAYBOOK,
|
|
36
36
|
PROPERTY_SCALE_MAP: () => PROPERTY_SCALE_MAP,
|
|
37
37
|
REFLECT_MODES: () => REFLECT_MODES,
|
|
38
|
+
REGISTRY_PRODUCT_ID: () => REGISTRY_PRODUCT_ID,
|
|
38
39
|
STRATEGY_OUTCOMES_PLAYBOOK: () => STRATEGY_OUTCOMES_PLAYBOOK,
|
|
39
40
|
UPG_ACTIVE_TYPES: () => UPG_ACTIVE_TYPES,
|
|
40
41
|
UPG_ANTI_PATTERNS: () => UPG_ANTI_PATTERNS,
|
|
@@ -706,7 +707,9 @@ var UPG_ENTITY_META = [
|
|
|
706
707
|
{ name: "objective", type_id: "ent_004", maturity: "stable", since: "0.1.0" },
|
|
707
708
|
{ name: "key_result", type_id: "ent_005", maturity: "stable", since: "0.1.0" },
|
|
708
709
|
{ name: "metric", type_id: "ent_006", maturity: "stable", since: "0.1.0" },
|
|
709
|
-
|
|
710
|
+
// F7 (UPG-673): graduated proposed → stable at v0.9.x — proposed since 0.2.2,
|
|
711
|
+
// the metric-quality assessment artefact is settled with no open restructure.
|
|
712
|
+
{ name: "metric_quality_assessment", type_id: "ent_339", maturity: "stable", since: "0.2.2" },
|
|
710
713
|
{ name: "vision", type_id: "ent_007", maturity: "stable", since: "0.1.0" },
|
|
711
714
|
{ name: "mission", type_id: "ent_008", maturity: "stable", since: "0.1.0" },
|
|
712
715
|
{ name: "strategic_theme", type_id: "ent_009", maturity: "stable", since: "0.1.0" },
|
|
@@ -763,8 +766,11 @@ var UPG_ENTITY_META = [
|
|
|
763
766
|
{ name: "market_segment", type_id: "ent_036", maturity: "stable", since: "0.1.0" },
|
|
764
767
|
{ name: "competitive_analysis", type_id: "ent_037", maturity: "stable", since: "0.1.0" },
|
|
765
768
|
// Classification taxonomy hosted by competitive_analysis.
|
|
766
|
-
|
|
767
|
-
|
|
769
|
+
// F7 (UPG-673): graduated proposed → stable at v0.9.x — two minor releases
|
|
770
|
+
// stable since 0.4.0, the taxonomy-axis/value pair backs the competitive-
|
|
771
|
+
// analysis classification spine with no open rename/restructure ticket.
|
|
772
|
+
{ name: "classification_axis", type_id: "ent_346", maturity: "stable", since: "0.4.0" },
|
|
773
|
+
{ name: "classification_value", type_id: "ent_347", maturity: "stable", since: "0.4.0" },
|
|
768
774
|
// ── UX Research ──
|
|
769
775
|
{ name: "research_study", type_id: "ent_038", maturity: "stable", since: "0.1.0" },
|
|
770
776
|
{ name: "research_insight", type_id: "ent_039", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "insight" },
|
|
@@ -804,8 +810,10 @@ var UPG_ENTITY_META = [
|
|
|
804
810
|
{ name: "journey_phase", type_id: "ent_330", maturity: "proposed", since: "0.2.0" },
|
|
805
811
|
{ name: "journey_action", type_id: "ent_331", maturity: "proposed", since: "0.2.0" },
|
|
806
812
|
{ name: "design_decision", type_id: "ent_319", maturity: "deprecated", since: "0.2.0", deprecated_in: "0.2.0", replacement: "decision" },
|
|
807
|
-
|
|
808
|
-
|
|
813
|
+
// F7 (UPG-673): graduated proposed → stable at v0.9.x — proposed since 0.2.0,
|
|
814
|
+
// the brand-identity set (logo + imagery) is settled with no open rename.
|
|
815
|
+
{ name: "brand_logo", type_id: "ent_321", maturity: "stable", since: "0.2.0" },
|
|
816
|
+
{ name: "brand_imagery", type_id: "ent_322", maturity: "stable", since: "0.2.0" },
|
|
809
817
|
// ── Product Spec ──
|
|
810
818
|
{ name: "feature_area", type_id: "ent_314", maturity: "stable", since: "0.1.0" },
|
|
811
819
|
{ name: "feature", type_id: "ent_071", maturity: "stable", since: "0.1.0" },
|
|
@@ -821,6 +829,15 @@ var UPG_ENTITY_META = [
|
|
|
821
829
|
// alias. `story_task` (the original work half) was already collapsed into
|
|
822
830
|
// canonical `task` at v0.4.0. So the canonical shape is: user_story (statement)
|
|
823
831
|
// + task (work), linked by `task_implements_user_story`.
|
|
832
|
+
//
|
|
833
|
+
// F7 (UPG-673) — DEFERRED, deliberately kept `proposed`. The audit flagged
|
|
834
|
+
// user_story as a stable-spine candidate, but the v0.7.0 re-canon contract
|
|
835
|
+
// (UPG-571) freezes maturity at `proposed` until the re-canonicalised name
|
|
836
|
+
// has soaked across a full migration window. `user-story-split.test.ts`
|
|
837
|
+
// ("user_story is canonical again (ent_073, proposed, not deprecated)")
|
|
838
|
+
// asserts `proposed` as the post-re-canon invariant. Graduating here would
|
|
839
|
+
// break that contract; promotion is a separate, ticketed decision once the
|
|
840
|
+
// story_statement → user_story migration has fully aged out.
|
|
824
841
|
{ name: "user_story", type_id: "ent_073", maturity: "proposed", since: "0.1.0" },
|
|
825
842
|
{ name: "story_statement", type_id: "ent_342", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.7.0", replacement: "user_story" },
|
|
826
843
|
{ name: "story_task", type_id: "ent_343", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.4.0", replacement: "task" },
|
|
@@ -1837,8 +1854,11 @@ var UPG_EDGE_CATALOG = {
|
|
|
1837
1854
|
value_proposition_targets_persona_cross_domain: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "value_proposition", target_type: "persona" },
|
|
1838
1855
|
revenue_stream_drives_metric: { forward_verb: "drives", reverse_verb: "driven_by", classification: "cross-domain", source_type: "revenue_stream", target_type: "metric" },
|
|
1839
1856
|
// Ring 5 structural edges
|
|
1840
|
-
|
|
1841
|
-
|
|
1857
|
+
// (UPG-668, P-I) These three edges name `funnel_step` but were typed against
|
|
1858
|
+
// `funnel`, so they resolved from the wrong side and were invisible on the
|
|
1859
|
+
// funnel_step card. Repointed to `funnel_step`; keys unchanged.
|
|
1860
|
+
funnel_step_maps_to_journey_step: { forward_verb: "maps_to", reverse_verb: "mapped_by", classification: "cross-domain", source_type: "funnel_step", target_type: "journey_step" },
|
|
1861
|
+
customer_journey_stage_contains_funnel_step: { forward_verb: "contains", reverse_verb: "contained_in", classification: "cross-domain", source_type: "customer_journey_stage", target_type: "funnel_step" },
|
|
1842
1862
|
customer_journey_stage_spans_journey_step: { forward_verb: "spans", reverse_verb: "spanned_by", classification: "cross-domain", source_type: "customer_journey_stage", target_type: "journey_step" },
|
|
1843
1863
|
dependency_blocks_team: { forward_verb: "blocks", reverse_verb: "blocked_by", classification: "cross-domain", source_type: "dependency", target_type: "team" },
|
|
1844
1864
|
dependency_depends_on_team: { forward_verb: "depends_on", reverse_verb: "depended_on_by", classification: "cross-domain", source_type: "dependency", target_type: "team" },
|
|
@@ -1891,7 +1911,7 @@ var UPG_EDGE_CATALOG = {
|
|
|
1891
1911
|
positioning_within_market_segment: { forward_verb: "within", reverse_verb: "positioned_by", classification: "cross-domain", source_type: "positioning", target_type: "market_segment" },
|
|
1892
1912
|
ideal_customer_profile_targets_market_segment: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "ideal_customer_profile", target_type: "market_segment" },
|
|
1893
1913
|
launch_amplified_by_marketing_channel: { forward_verb: "amplified_by", reverse_verb: "amplifies", classification: "cross-domain", source_type: "launch", target_type: "marketing_channel" },
|
|
1894
|
-
sales_motion_qualifies_via_funnel_step: { forward_verb: "qualifies_via", reverse_verb: "qualifies_for", classification: "cross-domain", source_type: "sales_motion", target_type: "
|
|
1914
|
+
sales_motion_qualifies_via_funnel_step: { forward_verb: "qualifies_via", reverse_verb: "qualifies_for", classification: "cross-domain", source_type: "sales_motion", target_type: "funnel_step" },
|
|
1895
1915
|
objection_sourced_from_quote: { forward_verb: "sourced_from", reverse_verb: "surfaced_objection", classification: "cross-domain", source_type: "objection", target_type: "quote" },
|
|
1896
1916
|
proof_point_derived_from_evidence: { forward_verb: "derived_from", reverse_verb: "evidences", classification: "cross-domain", source_type: "proof_point", target_type: "evidence" },
|
|
1897
1917
|
proof_point_derived_from_insight: { forward_verb: "derived_from", reverse_verb: "evidences", classification: "cross-domain", source_type: "proof_point", target_type: "insight" },
|
|
@@ -2905,7 +2925,104 @@ var UPG_EDGE_CATALOG = {
|
|
|
2905
2925
|
// to `journey_step_reveals_need` (existing); both express "what
|
|
2906
2926
|
// research surfaces at this step". Useful for any journey-based
|
|
2907
2927
|
// research method (CX mapping, service blueprint, behavioural cohort).
|
|
2908
|
-
journey_step_yields_observation: { forward_verb: "yields", reverse_verb: "yielded_in", classification: "cross-domain", source_type: "journey_step", target_type: "observation" }
|
|
2928
|
+
journey_step_yields_observation: { forward_verb: "yields", reverse_verb: "yielded_in", classification: "cross-domain", source_type: "journey_step", target_type: "observation" },
|
|
2929
|
+
// ── Part 11: F6 (UPG-672) dead-end & missing-bridge pass ────────────────────
|
|
2930
|
+
// P-A (scored / synthesis / verdict leaves with 0 outbound) + P-D (missing
|
|
2931
|
+
// forward bridges) from the 36-domain wiring audit. Every edge below closes a
|
|
2932
|
+
// confirmed dead-end or missing direction. Naming respects the F2 prefix gate
|
|
2933
|
+
// (key begins with its `source_type` as a whole token) and the F3 dup gate (no
|
|
2934
|
+
// source→target pair already in the catalog). Verified against the catalog at
|
|
2935
|
+
// build time; see the F6 commit body for the audit ledger references.
|
|
2936
|
+
// ── F6: Priority 1 — both-sides-verified cross-domain bridges ──────────────
|
|
2937
|
+
// data_classification ↔ privacy_policy (security SEC-3/L5 + legal). The
|
|
2938
|
+
// classification leaf reached only data_source; it could not reach the policy
|
|
2939
|
+
// that governs how it must be handled. A privacy_policy GOVERNS a data
|
|
2940
|
+
// classification (sets retention / handling rules for that sensitivity tier).
|
|
2941
|
+
data_classification_governed_by_privacy_policy: { forward_verb: "governed_by", reverse_verb: "governs", classification: "cross-domain", source_type: "data_classification", target_type: "privacy_policy" },
|
|
2942
|
+
// design_component → a11y conformance (design_system DS-3 + accessibility A).
|
|
2943
|
+
// The whole conformance DIRECTION was missing: a11y_issue → design_component
|
|
2944
|
+
// existed (defect points back), but no component → standard/guideline link
|
|
2945
|
+
// expressing "this component CONFORMS TO this rule". Both the testable
|
|
2946
|
+
// standard and the human-readable guideline are valid conformance targets.
|
|
2947
|
+
design_component_conforms_to_a11y_standard: { forward_verb: "conforms_to", reverse_verb: "governs_conformance_of", classification: "cross-domain", source_type: "design_component", target_type: "a11y_standard" },
|
|
2948
|
+
design_component_conforms_to_a11y_guideline: { forward_verb: "conforms_to", reverse_verb: "governs_conformance_of", classification: "cross-domain", source_type: "design_component", target_type: "a11y_guideline" },
|
|
2949
|
+
// feature_request → feature ship-closure (feedback + product_spec). A request
|
|
2950
|
+
// could reach an opportunity but never the feature that ships it, so the loop
|
|
2951
|
+
// from "user asked" to "we built it" had no closing edge. A feature_request
|
|
2952
|
+
// BECOMES a feature when the team commits to building it.
|
|
2953
|
+
feature_request_becomes_feature: { forward_verb: "becomes", reverse_verb: "originated_from", classification: "cross-domain", source_type: "feature_request", target_type: "feature" },
|
|
2954
|
+
// objective → outcome (OKR spine). objective reached key_result and metric but
|
|
2955
|
+
// not the outcome it exists to move; the strategic spine was severed at its
|
|
2956
|
+
// anchor (0 outbound to outcome). An objective ADVANCES an outcome. Intra-
|
|
2957
|
+
// domain (both in strategy) and directional → causal.
|
|
2958
|
+
objective_advances_outcome: { forward_verb: "advances", reverse_verb: "advanced_by", classification: "causal", source_type: "objective", target_type: "outcome" },
|
|
2959
|
+
// ── F6: Priority 2 — scored / synthesis / verdict dead-end leaves (P-A) ─────
|
|
2960
|
+
// desired_outcome (Ulwick-scored: importance × satisfaction) had 0 outbound —
|
|
2961
|
+
// the scores could not flow anywhere. An under-served desired_outcome REVEALS
|
|
2962
|
+
// an opportunity, and is QUANTIFIED BY the metric that tracks its satisfaction.
|
|
2963
|
+
desired_outcome_reveals_opportunity: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "desired_outcome", target_type: "opportunity" },
|
|
2964
|
+
desired_outcome_quantified_by_metric: { forward_verb: "quantified_by", reverse_verb: "quantifies", classification: "cross-domain", source_type: "desired_outcome", target_type: "metric" },
|
|
2965
|
+
// feasibility_study + design_sprint: discovery VERDICTS with 0 outbound — they
|
|
2966
|
+
// could not reach the decision, solution, or learning they exist to produce.
|
|
2967
|
+
// A study/sprint INFORMS a decision, RECOMMENDS a solution, and PRODUCES a
|
|
2968
|
+
// learning. solution is intra-discovery (semantic); decision (strategy) and
|
|
2969
|
+
// learning (validation) are cross-domain.
|
|
2970
|
+
feasibility_study_informs_decision: { forward_verb: "informs", reverse_verb: "informed_by", classification: "cross-domain", source_type: "feasibility_study", target_type: "decision" },
|
|
2971
|
+
feasibility_study_recommends_solution: { forward_verb: "recommends", reverse_verb: "recommended_by", classification: "semantic", source_type: "feasibility_study", target_type: "solution" },
|
|
2972
|
+
feasibility_study_produces_learning: { forward_verb: "produces", reverse_verb: "produced_by", classification: "cross-domain", source_type: "feasibility_study", target_type: "learning" },
|
|
2973
|
+
design_sprint_informs_decision: { forward_verb: "informs", reverse_verb: "informed_by", classification: "cross-domain", source_type: "design_sprint", target_type: "decision" },
|
|
2974
|
+
design_sprint_recommends_solution: { forward_verb: "recommends", reverse_verb: "recommended_by", classification: "semantic", source_type: "design_sprint", target_type: "solution" },
|
|
2975
|
+
design_sprint_produces_learning: { forward_verb: "produces", reverse_verb: "produced_by", classification: "cross-domain", source_type: "design_sprint", target_type: "learning" },
|
|
2976
|
+
// affinity_cluster → observation (user_research). A cluster synthesised an
|
|
2977
|
+
// insight but could not OWN the raw observations it groups; the cluster's
|
|
2978
|
+
// membership was unrepresentable. Intra-domain ownership → hierarchy.
|
|
2979
|
+
affinity_cluster_groups_observation: { forward_verb: "groups", reverse_verb: "grouped_in", classification: "hierarchy", source_type: "affinity_cluster", target_type: "observation" },
|
|
2980
|
+
// feedback_theme → opportunity (feedback). A theme validated needs and
|
|
2981
|
+
// surfaced insights but could not point at the opportunity it implies — the
|
|
2982
|
+
// theme could not become actionable discovery input.
|
|
2983
|
+
feedback_theme_reveals_opportunity: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "feedback_theme", target_type: "opportunity" },
|
|
2984
|
+
// competitor_feature → capability (market_intelligence). A competitor feature
|
|
2985
|
+
// inspired our solution/feature but could not map to the capability it
|
|
2986
|
+
// demonstrates — competitive capability benchmarking was unrepresentable.
|
|
2987
|
+
competitor_feature_benchmarks_capability: { forward_verb: "benchmarks", reverse_verb: "benchmarked_by", classification: "cross-domain", source_type: "competitor_feature", target_type: "capability" },
|
|
2988
|
+
// switching_cost → competitor (user). A switching cost is the friction of
|
|
2989
|
+
// leaving an incumbent, but the leaf had 0 outbound — it could not name the
|
|
2990
|
+
// competitor it locks the user into. It LOCKS IN a competitor.
|
|
2991
|
+
switching_cost_locks_in_competitor: { forward_verb: "locks_in", reverse_verb: "locked_in_by", classification: "cross-domain", source_type: "switching_cost", target_type: "competitor" },
|
|
2992
|
+
// ── F6: region tail — confirmed dead-end leaves across remaining domains ────
|
|
2993
|
+
// test_result (testing) had 0 outbound — a failing result could not file the
|
|
2994
|
+
// defect it found. A test_result REPORTS a bug.
|
|
2995
|
+
test_result_reports_bug: { forward_verb: "reports", reverse_verb: "reported_by", classification: "cross-domain", source_type: "test_result", target_type: "bug" },
|
|
2996
|
+
// content_piece → social_post (content → marketing). Content reached messaging
|
|
2997
|
+
// and campaigns but not the social post it is repurposed into — the atomisation
|
|
2998
|
+
// step had no edge.
|
|
2999
|
+
content_piece_repurposed_as_social_post: { forward_verb: "repurposed_as", reverse_verb: "repurposed_from", classification: "cross-domain", source_type: "content_piece", target_type: "social_post" },
|
|
3000
|
+
// translation_key (localisation) had 0 outbound — it could neither reach the
|
|
3001
|
+
// content it localises nor the locale it targets. Both bridges close the leaf.
|
|
3002
|
+
// translation_key → content_piece is cross-domain; → locale is intra-domain.
|
|
3003
|
+
translation_key_localises_content_piece: { forward_verb: "localises", reverse_verb: "localised_by", classification: "cross-domain", source_type: "translation_key", target_type: "content_piece" },
|
|
3004
|
+
translation_key_targets_locale: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "semantic", source_type: "translation_key", target_type: "locale" },
|
|
3005
|
+
// partner_revenue_share → revenue_stream (ecosystem → business_model). The
|
|
3006
|
+
// share governed a partner tier but never fed the revenue stream it
|
|
3007
|
+
// contributes to — partner economics could not roll up to the model.
|
|
3008
|
+
partner_revenue_share_feeds_revenue_stream: { forward_verb: "feeds", reverse_verb: "fed_by", classification: "cross-domain", source_type: "partner_revenue_share", target_type: "revenue_stream" },
|
|
3009
|
+
// retrospective (team_org) had 0 outbound — its outputs (learnings, decisions/
|
|
3010
|
+
// action items) could not leave the ceremony. A retrospective PRODUCES a
|
|
3011
|
+
// learning and YIELDS a decision. Both targets cross-domain.
|
|
3012
|
+
retrospective_produces_learning: { forward_verb: "produces", reverse_verb: "produced_in", classification: "cross-domain", source_type: "retrospective", target_type: "learning" },
|
|
3013
|
+
retrospective_yields_decision: { forward_verb: "yields", reverse_verb: "decided_in", classification: "cross-domain", source_type: "retrospective", target_type: "decision" },
|
|
3014
|
+
// status_report → milestone (program_mgmt). A report had 0 outbound; it could
|
|
3015
|
+
// not name the milestone whose status it reports. Intra-domain → semantic.
|
|
3016
|
+
status_report_reports_on_milestone: { forward_verb: "reports_on", reverse_verb: "reported_in", classification: "semantic", source_type: "status_report", target_type: "milestone" },
|
|
3017
|
+
// quote_document → deal (sales). A quote had 0 outbound; it could not advance
|
|
3018
|
+
// the deal it prices. Intra-domain and directional → causal.
|
|
3019
|
+
quote_document_advances_deal: { forward_verb: "advances", reverse_verb: "advanced_by", classification: "causal", source_type: "quote_document", target_type: "deal" },
|
|
3020
|
+
// data_quality_rule → data_source (data_analytics). A quality rule had 0
|
|
3021
|
+
// outbound; it could not name the source it governs. Intra-domain → semantic.
|
|
3022
|
+
data_quality_rule_governs_data_source: { forward_verb: "governs", reverse_verb: "governed_by", classification: "semantic", source_type: "data_quality_rule", target_type: "data_source" },
|
|
3023
|
+
// press_release → launch (marketing → go_to_market). A press release had 0
|
|
3024
|
+
// outbound; it could not name the launch it announces.
|
|
3025
|
+
press_release_announces_launch: { forward_verb: "announces", reverse_verb: "announced_by", classification: "cross-domain", source_type: "press_release", target_type: "launch" }
|
|
2909
3026
|
};
|
|
2910
3027
|
var UPG_POLYMORPHIC_EDGE_KEYS = [
|
|
2911
3028
|
// Universal semantic verbs
|
|
@@ -2968,8 +3085,10 @@ var UPG_CROSS_EDGE_TYPES = [
|
|
|
2968
3085
|
"cannibalises",
|
|
2969
3086
|
"succeeds",
|
|
2970
3087
|
"hosts",
|
|
2971
|
-
"contributes_to"
|
|
3088
|
+
"contributes_to",
|
|
3089
|
+
"instance_of"
|
|
2972
3090
|
];
|
|
3091
|
+
var REGISTRY_PRODUCT_ID = "registry";
|
|
2973
3092
|
|
|
2974
3093
|
// src/registry/entity-type-resolution.ts
|
|
2975
3094
|
var TYPES = getTypes();
|
|
@@ -3252,7 +3371,11 @@ var UPG_VALID_CHILDREN = {
|
|
|
3252
3371
|
"survey_response"
|
|
3253
3372
|
],
|
|
3254
3373
|
observation: ["quote"],
|
|
3255
|
-
|
|
3374
|
+
// F6 (UPG-672): affinity_cluster owns the observations it groups, in addition
|
|
3375
|
+
// to the insights it synthesises. Pairs with `affinity_cluster_groups_observation`
|
|
3376
|
+
// in the edge catalog (hierarchy). An observation can be both directly owned by
|
|
3377
|
+
// its research_study and grouped under an affinity_cluster (multi-parent grammar).
|
|
3378
|
+
affinity_cluster: ["insight", "observation"],
|
|
3256
3379
|
// insight refines into insight; a raw insight can be distilled
|
|
3257
3380
|
// into a more specific insight (refines_into chain).
|
|
3258
3381
|
// v0.5.8 (UPG-528 Part 2d): insights own their evidencing quotes;
|
|
@@ -10470,6 +10593,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10470
10593
|
},
|
|
10471
10594
|
// LearningPathProperties: Learning path.
|
|
10472
10595
|
learning_path: {
|
|
10596
|
+
path_order: { type: "number", description: "Display order of this path within a curriculum or program (0-indexed). The scalar ordering convention shared with `journey_step.step_order` and `journey_action.action_order` (UPG-663 / UPG-674). Makes a learning_path a deterministically orderable sequence among sibling paths rather than a star." },
|
|
10473
10597
|
path_difficulty: { type: "string", enum: ["beginner", "intermediate", "advanced"], description: "Overall difficulty level of the learning path" },
|
|
10474
10598
|
item_count: { type: "number", description: "Number of items (tutorials, videos, etc.) in the path" },
|
|
10475
10599
|
estimated_hours: { type: "number", description: "Estimated total hours to complete the path" },
|
|
@@ -10619,6 +10743,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10619
10743
|
},
|
|
10620
10744
|
// MilestoneProperties: Milestone.
|
|
10621
10745
|
milestone: {
|
|
10746
|
+
milestone_order: { type: "number", description: "Display order of this milestone within its parent project (0-indexed). The scalar ordering convention shared with `journey_step.step_order` and `journey_action.action_order` (UPG-663 / UPG-674). Orders the delivery milestones a project moves through, independent of `due_date`." },
|
|
10622
10747
|
due_date: { type: "string", description: "Target due date (ISO format)" },
|
|
10623
10748
|
met_on_time: { type: "boolean", description: "Whether the milestone was met on time" }
|
|
10624
10749
|
},
|
|
@@ -10823,6 +10948,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
10823
10948
|
},
|
|
10824
10949
|
// PartnerTierProperties: Partner tier.
|
|
10825
10950
|
partner_tier: {
|
|
10951
|
+
tier_order: { type: "number", description: "Display order of this tier among sibling partner tiers (1 = first tier shown). Mirrors `pricing_tier.tier_order`; part of the spec-wide `*_order` sequence convention (UPG-663 / UPG-674). Distinct from `tier_level`, which is a prestige rank, not a presentation order." },
|
|
10826
10952
|
tier_level: { type: "number", description: "Numeric rank of the tier (higher = more prestigious)" },
|
|
10827
10953
|
requirements: { type: "string[]", description: "What a partner must achieve to reach this tier" },
|
|
10828
10954
|
benefits: { type: "string[]", description: "Benefits granted at this tier level" }
|
|
@@ -11245,6 +11371,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
11245
11371
|
},
|
|
11246
11372
|
// ScreenStateProperties: Specific state of a screen.
|
|
11247
11373
|
screen_state: {
|
|
11374
|
+
state_order: { type: "number", description: "Display order of this state within its parent screen (0-indexed). The scalar ordering convention shared with `journey_step.step_order` and `journey_action.action_order` (UPG-663 / UPG-674). Orders the states a screen moves through (e.g. skeleton, loading, populated)." },
|
|
11248
11375
|
state_name: { type: "string", enum: ["empty", "loading", "error", "populated", "skeleton", "partial"], description: "State" },
|
|
11249
11376
|
trigger: { type: "string", description: "Cause for entering this state" },
|
|
11250
11377
|
condition: { type: "string", description: "Data or environmental condition the state represents" },
|
|
@@ -11757,6 +11884,7 @@ var UPG_PROPERTY_SCHEMA = {
|
|
|
11757
11884
|
},
|
|
11758
11885
|
// UserFlowProperties: User flow.
|
|
11759
11886
|
user_flow: {
|
|
11887
|
+
flow_order: { type: "number", description: "Display order of this flow among sibling flows (0-indexed). The scalar ordering convention shared with `journey_step.step_order` and `journey_action.action_order` (UPG-663 / UPG-674). The free-text `steps` array below still captures the within-flow narrative; this scalar makes the flow itself a deterministically orderable sibling." },
|
|
11760
11888
|
trigger: { type: "string", description: "Initiating event" },
|
|
11761
11889
|
steps: { type: "string[]", description: "Ordered steps" },
|
|
11762
11890
|
success_state: { type: "string", description: "Successful completion" },
|
|
@@ -17820,7 +17948,10 @@ var PRIORITY_LABELS = [
|
|
|
17820
17948
|
{
|
|
17821
17949
|
id: "solution",
|
|
17822
17950
|
canonical_label: "Solution",
|
|
17823
|
-
|
|
17951
|
+
// 'concept' stripped (P-B / UPG-670): bare "concept" was shared with the
|
|
17952
|
+
// distinct `design_concept` type. `design_concept` keeps it; here a search
|
|
17953
|
+
// for a solution uses "approach" / "proposed solution".
|
|
17954
|
+
alt_labels: ["proposed solution", "solution idea", "approach"],
|
|
17824
17955
|
framework_labels: {
|
|
17825
17956
|
ost: "Solution",
|
|
17826
17957
|
design_thinking: "Solution",
|
|
@@ -17983,7 +18114,10 @@ var PRIORITY_LABELS = [
|
|
|
17983
18114
|
{
|
|
17984
18115
|
id: "outcome",
|
|
17985
18116
|
canonical_label: "Outcome",
|
|
17986
|
-
|
|
18117
|
+
// 'desired outcome' stripped (P-B / UPG-670): it was the canonical label of
|
|
18118
|
+
// the distinct `desired_outcome` (Ulwick JTBD) type. The OST framework_label
|
|
18119
|
+
// below still surfaces "Desired Outcome" in OST context, framework-scoped.
|
|
18120
|
+
alt_labels: ["product outcome", "business outcome", "target outcome"],
|
|
17987
18121
|
framework_labels: {
|
|
17988
18122
|
ost: "Desired Outcome",
|
|
17989
18123
|
okr_tree: "Outcome"
|
|
@@ -18011,7 +18145,10 @@ var PRIORITY_LABELS = [
|
|
|
18011
18145
|
{
|
|
18012
18146
|
id: "feature",
|
|
18013
18147
|
canonical_label: "Feature",
|
|
18014
|
-
|
|
18148
|
+
// 'capability' stripped (P-B / UPG-670): it is the canonical label of the
|
|
18149
|
+
// distinct `capability` type (Wardley / DDD). A search for "capability" must
|
|
18150
|
+
// resolve there, not to a feature.
|
|
18151
|
+
alt_labels: ["product feature", "functionality"],
|
|
18015
18152
|
framework_labels: {
|
|
18016
18153
|
rice: "Scored Item",
|
|
18017
18154
|
moscow: "Prioritised Item",
|
|
@@ -18082,7 +18219,10 @@ var PRIORITY_LABELS = [
|
|
|
18082
18219
|
{
|
|
18083
18220
|
id: "distribution_channel",
|
|
18084
18221
|
canonical_label: "Distribution Channel",
|
|
18085
|
-
|
|
18222
|
+
// bare 'channel' stripped (P-B / UPG-670): shared 3-way with
|
|
18223
|
+
// `acquisition_channel` and `marketing_channel`. BMC/Lean-Canvas framework
|
|
18224
|
+
// contexts still surface "Channel" via framework_labels below.
|
|
18225
|
+
alt_labels: ["distribution channel", "sales channel", "delivery channel", "distribution"],
|
|
18086
18226
|
framework_labels: {
|
|
18087
18227
|
bmc: "Channel",
|
|
18088
18228
|
lean_canvas: "Channel"
|
|
@@ -18262,7 +18402,8 @@ var PRIORITY_LABELS = [
|
|
|
18262
18402
|
];
|
|
18263
18403
|
var STANDARD_LABELS = {
|
|
18264
18404
|
// Strategic layer
|
|
18265
|
-
|
|
18405
|
+
// 'service' stripped (P-B / UPG-670): canonical label of the distinct `service` type.
|
|
18406
|
+
product: { alt_labels: ["offering", "app", "platform"] },
|
|
18266
18407
|
vision: { alt_labels: ["product vision", "north star vision", "long-term vision"] },
|
|
18267
18408
|
mission: { alt_labels: ["mission statement", "purpose"] },
|
|
18268
18409
|
strategic_theme: { alt_labels: ["focus area", "strategic focus area"] },
|
|
@@ -18280,7 +18421,8 @@ var STANDARD_LABELS = {
|
|
|
18280
18421
|
design_sprint: { alt_labels: ["sprint", "gv sprint", "google ventures sprint"] },
|
|
18281
18422
|
// Validation layer
|
|
18282
18423
|
learning: { alt_labels: ["validated learning", "lesson learned", "takeaway"] },
|
|
18283
|
-
|
|
18424
|
+
// 'experiment plan' stripped (P-B / UPG-670): canonical label of the distinct `experiment_plan` type.
|
|
18425
|
+
test_plan: { alt_labels: ["test strategy", "validation plan"] },
|
|
18284
18426
|
research_plan: { alt_labels: ["study plan", "research brief"] },
|
|
18285
18427
|
evidence: { alt_labels: ["proof", "supporting data", "signal"] },
|
|
18286
18428
|
variant: { alt_labels: ["test variant", "experiment arm", "variation"] },
|
|
@@ -18288,7 +18430,9 @@ var STANDARD_LABELS = {
|
|
|
18288
18430
|
competitor: { alt_labels: ["rival", "alternative", "competitive product", "competing product"] },
|
|
18289
18431
|
competitor_feature: { alt_labels: ["competitive feature", "rival capability"] },
|
|
18290
18432
|
market_trend: { alt_labels: ["trend", "industry trend", "macro trend"] },
|
|
18291
|
-
|
|
18433
|
+
// bare 'segment' stripped (P-B / UPG-670): shared 2-way with `behavioral_segment`.
|
|
18434
|
+
// 'market segment' is the qualified, unambiguous form.
|
|
18435
|
+
market_segment: { alt_labels: ["market segment", "market slice", "tam segment", "sam segment"] },
|
|
18292
18436
|
competitive_analysis: { alt_labels: ["competitor analysis", "competitive landscape", "market analysis"] },
|
|
18293
18437
|
// UX Research layer
|
|
18294
18438
|
research_study: { alt_labels: ["study", "user study", "research project", "ux study"] },
|
|
@@ -18324,7 +18468,8 @@ var STANDARD_LABELS = {
|
|
|
18324
18468
|
brand_typography: { alt_labels: ["typeface", "font family", "type system"] },
|
|
18325
18469
|
brand_voice: { alt_labels: ["tone of voice", "brand tone", "writing style"] },
|
|
18326
18470
|
// Product Specification layer
|
|
18327
|
-
|
|
18471
|
+
// 'initiative' stripped (P-B / UPG-670): canonical label of the distinct `initiative` type.
|
|
18472
|
+
epic: { alt_labels: ["large story", "feature set"] },
|
|
18328
18473
|
feature_area: { alt_labels: ["feature group", "capability area", "module"] },
|
|
18329
18474
|
acceptance_criterion: { alt_labels: ["ac", "done criterion", "acceptance criteria", "definition of done"] },
|
|
18330
18475
|
release: { alt_labels: ["version", "ship", "launch version", "build"] },
|
|
@@ -18338,8 +18483,10 @@ var STANDARD_LABELS = {
|
|
|
18338
18483
|
// Engineering layer
|
|
18339
18484
|
bounded_context: { alt_labels: ["context", "domain boundary", "module boundary"] },
|
|
18340
18485
|
service: { alt_labels: ["microservice", "backend service", "api service"] },
|
|
18341
|
-
|
|
18342
|
-
|
|
18486
|
+
// 'event' stripped (P-B / UPG-670): canonical label of the distinct `event` type.
|
|
18487
|
+
domain_event: { alt_labels: ["system event", "business event"] },
|
|
18488
|
+
// 'contract' stripped (P-B / UPG-670): canonical label of the distinct `contract` (legal) type.
|
|
18489
|
+
api_contract: { alt_labels: ["api spec", "api schema", "openapi spec"] },
|
|
18343
18490
|
technical_debt_item: { alt_labels: ["tech debt", "debt", "tech debt item", "cleanup"] },
|
|
18344
18491
|
feature_flag: { alt_labels: ["flag", "toggle", "feature toggle", "release flag"] },
|
|
18345
18492
|
aggregate: { alt_labels: ["aggregate root", "ddd aggregate"] },
|
|
@@ -18352,15 +18499,19 @@ var STANDARD_LABELS = {
|
|
|
18352
18499
|
queue_topic: { alt_labels: ["topic", "message queue", "event bus topic", "pubsub topic"] },
|
|
18353
18500
|
build_artifact: { alt_labels: ["artifact", "binary", "docker image", "package"] },
|
|
18354
18501
|
code_repository: { alt_labels: ["repo", "repository", "git repo", "codebase"] },
|
|
18355
|
-
|
|
18502
|
+
// 'dependency' stripped (P-B / UPG-670): canonical label of the distinct `dependency` type.
|
|
18503
|
+
library_dependency: { alt_labels: ["package", "library", "npm package"] },
|
|
18356
18504
|
integration_pattern: { alt_labels: ["integration", "pattern", "middleware pattern"] },
|
|
18357
18505
|
external_api: { alt_labels: ["third-party api", "vendor api", "saas integration"] },
|
|
18358
18506
|
data_flow: { alt_labels: ["data movement", "data transfer", "pipeline flow"] },
|
|
18359
18507
|
// Growth layer
|
|
18360
|
-
|
|
18508
|
+
// bare 'channel' stripped (P-B / UPG-670): shared 3-way (see distribution_channel).
|
|
18509
|
+
acquisition_channel: { alt_labels: ["acquisition channel", "traffic source", "user source"] },
|
|
18361
18510
|
growth_campaign: { alt_labels: ["campaign", "marketing campaign", "ad campaign", "growth campaign"] },
|
|
18362
18511
|
cohort: { alt_labels: ["user cohort", "retention cohort", "signup cohort"] },
|
|
18363
|
-
|
|
18512
|
+
// bare 'segment' stripped (P-B / UPG-670): shared 2-way with `market_segment`.
|
|
18513
|
+
// 'behavioral segment' / 'user segment' keep the affordance unambiguously.
|
|
18514
|
+
behavioral_segment: { alt_labels: ["user segment", "audience segment", "behavioural segment"] },
|
|
18364
18515
|
growth_loop: { alt_labels: ["viral loop", "referral loop", "flywheel"] },
|
|
18365
18516
|
attribution_model: { alt_labels: ["attribution", "marketing attribution", "channel attribution"] },
|
|
18366
18517
|
// Business Model layer
|
|
@@ -18389,7 +18540,8 @@ var STANDARD_LABELS = {
|
|
|
18389
18540
|
retrospective: { alt_labels: ["retro", "sprint retro", "team retro", "post-mortem"] },
|
|
18390
18541
|
dependency: { alt_labels: ["team dependency", "cross-team dependency", "blocker"] },
|
|
18391
18542
|
department: { alt_labels: ["org unit", "division", "business unit"] },
|
|
18392
|
-
|
|
18543
|
+
// 'capability' stripped (P-B / UPG-670): canonical label of the distinct `capability` type.
|
|
18544
|
+
skill: { alt_labels: ["competency", "expertise"] },
|
|
18393
18545
|
ceremony: { alt_labels: ["ritual", "meeting cadence", "standup", "retrospective meeting"] },
|
|
18394
18546
|
capacity_plan: { alt_labels: ["resourcing plan", "staffing plan", "headcount plan"] },
|
|
18395
18547
|
// Data & Analytics layer
|
|
@@ -18399,7 +18551,8 @@ var STANDARD_LABELS = {
|
|
|
18399
18551
|
data_model: { alt_labels: ["erd", "entity relationship diagram", "schema model"] },
|
|
18400
18552
|
data_quality_rule: { alt_labels: ["data rule", "quality check", "data validation"] },
|
|
18401
18553
|
data_product: { alt_labels: ["data asset", "data offering"] },
|
|
18402
|
-
|
|
18554
|
+
// 'data flow' stripped (P-B / UPG-670): canonical label of the distinct `data_flow` type.
|
|
18555
|
+
data_pipeline: { alt_labels: ["etl", "elt", "ingestion pipeline"] },
|
|
18403
18556
|
data_lineage: { alt_labels: ["lineage", "data provenance", "data trail"] },
|
|
18404
18557
|
glossary_term: { alt_labels: ["term", "definition", "business term"] },
|
|
18405
18558
|
data_domain: { alt_labels: ["data area", "data subject area"] },
|
|
@@ -18441,7 +18594,8 @@ var STANDARD_LABELS = {
|
|
|
18441
18594
|
error_budget: { alt_labels: ["reliability budget", "downtime budget"] },
|
|
18442
18595
|
investigation: { alt_labels: ["incident investigation", "root cause analysis", "debugging"] },
|
|
18443
18596
|
postmortem: { alt_labels: ["post-mortem", "incident review", "rca", "root cause analysis"] },
|
|
18444
|
-
|
|
18597
|
+
// 'playbook' stripped (P-B / UPG-670): canonical label of the distinct `playbook` type.
|
|
18598
|
+
runbook: { alt_labels: ["operations guide", "sop", "standard operating procedure"] },
|
|
18445
18599
|
monitor: { alt_labels: ["health check", "synthetic monitor", "uptime check"] },
|
|
18446
18600
|
alert_rule: { alt_labels: ["alert", "pager rule", "notification rule"] },
|
|
18447
18601
|
release_strategy: { alt_labels: ["rollout strategy", "deployment strategy", "canary release"] },
|
|
@@ -18456,17 +18610,26 @@ var STANDARD_LABELS = {
|
|
|
18456
18610
|
security_control: { alt_labels: ["control", "safeguard", "countermeasure", "mitigation"] },
|
|
18457
18611
|
security_policy: { alt_labels: ["infosec policy", "security standard"] },
|
|
18458
18612
|
penetration_test: { alt_labels: ["pentest", "pen test", "security test"] },
|
|
18459
|
-
|
|
18613
|
+
// bare 'audit' / 'security assessment' stripped (P-B / UPG-670): both owned by
|
|
18614
|
+
// `security_audit`. A `security_review` is a code-review-scoped activity; the
|
|
18615
|
+
// qualified 'security code review' keeps it findable without colliding.
|
|
18616
|
+
security_review: { alt_labels: ["code review", "security code review"] },
|
|
18460
18617
|
data_classification: { alt_labels: ["classification", "sensitivity level", "data label"] },
|
|
18461
18618
|
access_policy: { alt_labels: ["iam policy", "rbac rule", "permission", "access control"] },
|
|
18462
18619
|
// Sales & Revenue layer
|
|
18463
|
-
|
|
18464
|
-
|
|
18620
|
+
// 'organization' stripped (P-B / UPG-670): canonical label of the distinct `organization` type.
|
|
18621
|
+
account: { alt_labels: ["customer account", "client"] },
|
|
18622
|
+
// 'person' stripped (P-B / UPG-670): canonical label of the distinct `person` type.
|
|
18623
|
+
contact: { alt_labels: ["buyer", "champion"] },
|
|
18465
18624
|
lead: { alt_labels: ["prospect", "mql", "sql", "marketing lead"] },
|
|
18466
|
-
|
|
18625
|
+
// 'opportunity' stripped (P-B / UPG-670): canonical label of the distinct `opportunity` (OST) type.
|
|
18626
|
+
deal: { alt_labels: ["sales opportunity", "opp"] },
|
|
18467
18627
|
pipeline_sales: { alt_labels: ["sales pipeline", "deal pipeline", "revenue pipeline"] },
|
|
18468
18628
|
pipeline_stage: { alt_labels: ["deal stage", "sales stage"] },
|
|
18469
|
-
|
|
18629
|
+
// bare 'quote' qualified to 'sales quote' (P-B / UPG-670): 'quote' is the
|
|
18630
|
+
// canonical label of the distinct `quote` type. The qualified form keeps the
|
|
18631
|
+
// sales-document search affordance without misresolving.
|
|
18632
|
+
quote_document: { alt_labels: ["sales quote", "proposal", "estimate", "quotation"] },
|
|
18470
18633
|
subscription: { alt_labels: ["recurring revenue", "saas subscription", "plan"] },
|
|
18471
18634
|
invoice: { alt_labels: ["bill", "payment request"] },
|
|
18472
18635
|
forecast: { alt_labels: ["revenue forecast", "sales forecast", "projection"] },
|
|
@@ -18487,7 +18650,8 @@ var STANDARD_LABELS = {
|
|
|
18487
18650
|
a11y_annotation: { alt_labels: ["accessibility annotation", "aria note"] },
|
|
18488
18651
|
// Marketing & Communications layer
|
|
18489
18652
|
marketing_strategy: { alt_labels: ["marketing plan", "growth strategy"] },
|
|
18490
|
-
|
|
18653
|
+
// bare 'channel' stripped (P-B / UPG-670): shared 3-way (see distribution_channel).
|
|
18654
|
+
marketing_channel: { alt_labels: ["marketing channel", "paid channel", "organic channel"] },
|
|
18491
18655
|
marketing_campaign_plan: { alt_labels: ["campaign plan", "launch campaign"] },
|
|
18492
18656
|
email_sequence: { alt_labels: ["drip campaign", "nurture sequence", "email flow"] },
|
|
18493
18657
|
social_post: { alt_labels: ["tweet", "linkedin post", "social media post"] },
|
|
@@ -18561,7 +18725,9 @@ var STANDARD_LABELS = {
|
|
|
18561
18725
|
agent_session: { alt_labels: ["session", "agent run", "agent conversation"] },
|
|
18562
18726
|
review_gate: { alt_labels: ["approval gate", "quality gate", "stage gate"] },
|
|
18563
18727
|
approval_record: { alt_labels: ["approval", "sign-off", "authorization"] },
|
|
18564
|
-
|
|
18728
|
+
// bare 'skill' qualified to 'agent skill' (P-B / UPG-670): 'skill' is the
|
|
18729
|
+
// canonical label of the distinct team_org `skill` type.
|
|
18730
|
+
agent_skill: { alt_labels: ["agent skill", "tool", "agent capability"] },
|
|
18565
18731
|
agent_hook: { alt_labels: ["hook", "trigger", "callback"] },
|
|
18566
18732
|
workflow_artifact: { alt_labels: ["artifact", "output artifact", "generated artifact"] },
|
|
18567
18733
|
// Portfolio layer
|
|
@@ -23705,6 +23871,96 @@ var UPG_ANTI_PATTERNS = [
|
|
|
23705
23871
|
stages: ["concept", "validation", "build", "beta", "launch", "growth"],
|
|
23706
23872
|
severity: "high",
|
|
23707
23873
|
source: { kind: "fundamental" }
|
|
23874
|
+
},
|
|
23875
|
+
// ── F5 (UPG-671): anti-pattern enforcement ────────────────────────────────
|
|
23876
|
+
// P-C from the 36-domain wiring audit: domain-guide anti-patterns described
|
|
23877
|
+
// in prose with no machine-checkable detector. These two map cleanly to a
|
|
23878
|
+
// RelationshipCheck (edge presence/absence) and are promoted here.
|
|
23879
|
+
{
|
|
23880
|
+
id: "insights-without-evidence",
|
|
23881
|
+
name: "Insights without evidence",
|
|
23882
|
+
description: "The graph has insight entities but none are backed by a primary-evidence link: no observation yields them (`observation_yields_insight`), no survey response evidences them (`survey_response_evidences_insight`), and no quote is attached (`insight_evidenced_by_quote`). An insight with no evidence behind it is an opinion wearing a research label.",
|
|
23883
|
+
structured_condition: {
|
|
23884
|
+
operator: "and",
|
|
23885
|
+
checks: [
|
|
23886
|
+
{ check: { type: "entity_count", entity_type: "insight", comparison: "nonzero" } },
|
|
23887
|
+
{
|
|
23888
|
+
check: {
|
|
23889
|
+
type: "relationship",
|
|
23890
|
+
source_type: "observation",
|
|
23891
|
+
edge_type: "observation_yields_insight",
|
|
23892
|
+
target_type: "insight",
|
|
23893
|
+
comparison: "not_exists"
|
|
23894
|
+
}
|
|
23895
|
+
},
|
|
23896
|
+
{
|
|
23897
|
+
check: {
|
|
23898
|
+
type: "relationship",
|
|
23899
|
+
source_type: "survey_response",
|
|
23900
|
+
edge_type: "survey_response_evidences_insight",
|
|
23901
|
+
target_type: "insight",
|
|
23902
|
+
comparison: "not_exists"
|
|
23903
|
+
}
|
|
23904
|
+
},
|
|
23905
|
+
{
|
|
23906
|
+
check: {
|
|
23907
|
+
type: "relationship",
|
|
23908
|
+
source_type: "insight",
|
|
23909
|
+
edge_type: "insight_evidenced_by_quote",
|
|
23910
|
+
target_type: "quote",
|
|
23911
|
+
comparison: "not_exists"
|
|
23912
|
+
}
|
|
23913
|
+
}
|
|
23914
|
+
]
|
|
23915
|
+
},
|
|
23916
|
+
why_it_matters: "Insights untethered from evidence cannot be trusted, contested, or traced. Downstream opportunities and design questions inherit an unfalsifiable claim.",
|
|
23917
|
+
remediation: "Back each insight with at least one primary record via `observation_yields_insight`, `survey_response_evidences_insight`, or `insight_evidenced_by_quote`. Capture the supporting observation or quote first.",
|
|
23918
|
+
stages: ["concept", "validation", "build", "beta", "launch", "growth", "mature"],
|
|
23919
|
+
severity: "high",
|
|
23920
|
+
source: { kind: "practitioner", attribution: "Steve Portigal, Interviewing Users" }
|
|
23921
|
+
},
|
|
23922
|
+
{
|
|
23923
|
+
id: "feature-requests-without-provenance",
|
|
23924
|
+
name: "Feature requests without provenance",
|
|
23925
|
+
description: "The graph has feature_request entities but none trace back to a source: no feedback program collects them (`feedback_program_collects_feature_request`), no customer feedback becomes one (`customer_feedback_becomes_feature_request`), and none originate from a behavioural segment (`feature_request_from_behavioral_segment`). A request with no provenance cannot be weighed against who asked or how many.",
|
|
23926
|
+
structured_condition: {
|
|
23927
|
+
operator: "and",
|
|
23928
|
+
checks: [
|
|
23929
|
+
{ check: { type: "entity_count", entity_type: "feature_request", comparison: "nonzero" } },
|
|
23930
|
+
{
|
|
23931
|
+
check: {
|
|
23932
|
+
type: "relationship",
|
|
23933
|
+
source_type: "feedback_program",
|
|
23934
|
+
edge_type: "feedback_program_collects_feature_request",
|
|
23935
|
+
target_type: "feature_request",
|
|
23936
|
+
comparison: "not_exists"
|
|
23937
|
+
}
|
|
23938
|
+
},
|
|
23939
|
+
{
|
|
23940
|
+
check: {
|
|
23941
|
+
type: "relationship",
|
|
23942
|
+
source_type: "customer_feedback",
|
|
23943
|
+
edge_type: "customer_feedback_becomes_feature_request",
|
|
23944
|
+
target_type: "feature_request",
|
|
23945
|
+
comparison: "not_exists"
|
|
23946
|
+
}
|
|
23947
|
+
},
|
|
23948
|
+
{
|
|
23949
|
+
check: {
|
|
23950
|
+
type: "relationship",
|
|
23951
|
+
source_type: "feature_request",
|
|
23952
|
+
edge_type: "feature_request_from_behavioral_segment",
|
|
23953
|
+
target_type: "behavioral_segment",
|
|
23954
|
+
comparison: "not_exists"
|
|
23955
|
+
}
|
|
23956
|
+
}
|
|
23957
|
+
]
|
|
23958
|
+
},
|
|
23959
|
+
why_it_matters: "Requests without a source get prioritised on volume of voice, not on the strength or fit of who is asking. The loudest channel wins by default.",
|
|
23960
|
+
remediation: "Attach provenance to each `feature_request` via `feedback_program_collects_feature_request`, `customer_feedback_becomes_feature_request`, or `feature_request_from_behavioral_segment` before it enters prioritisation.",
|
|
23961
|
+
stages: ["beta", "launch", "growth", "mature"],
|
|
23962
|
+
severity: "medium",
|
|
23963
|
+
source: { kind: "practitioner", attribution: "Marty Cagan, Inspired (product discovery)" }
|
|
23708
23964
|
}
|
|
23709
23965
|
];
|
|
23710
23966
|
function getAntiPatternById(id) {
|
|
@@ -24043,6 +24299,10 @@ var UPG_REGIONS = [
|
|
|
24043
24299
|
"strategy"
|
|
24044
24300
|
],
|
|
24045
24301
|
entities: [
|
|
24302
|
+
{
|
|
24303
|
+
type: "product",
|
|
24304
|
+
role: "container"
|
|
24305
|
+
},
|
|
24046
24306
|
{
|
|
24047
24307
|
type: "vision",
|
|
24048
24308
|
role: "root"
|
|
@@ -24082,7 +24342,11 @@ var UPG_REGIONS = [
|
|
|
24082
24342
|
{
|
|
24083
24343
|
type: "metric",
|
|
24084
24344
|
role: "leaf",
|
|
24085
|
-
notes: "
|
|
24345
|
+
notes: "also anchors Analytics; canonical home is Strategy"
|
|
24346
|
+
},
|
|
24347
|
+
{
|
|
24348
|
+
type: "metric_quality_assessment",
|
|
24349
|
+
role: "leaf"
|
|
24086
24350
|
},
|
|
24087
24351
|
{
|
|
24088
24352
|
type: "decision",
|
|
@@ -24093,6 +24357,10 @@ var UPG_REGIONS = [
|
|
|
24093
24357
|
type: "assumption",
|
|
24094
24358
|
role: "leaf"
|
|
24095
24359
|
},
|
|
24360
|
+
{
|
|
24361
|
+
type: "constraint",
|
|
24362
|
+
role: "leaf"
|
|
24363
|
+
},
|
|
24096
24364
|
{
|
|
24097
24365
|
type: "outcome",
|
|
24098
24366
|
role: "hub"
|
|
@@ -24206,7 +24474,7 @@ var UPG_REGIONS = [
|
|
|
24206
24474
|
{
|
|
24207
24475
|
type: "participant",
|
|
24208
24476
|
role: "leaf",
|
|
24209
|
-
notes: "research-resolved persona"
|
|
24477
|
+
notes: "research-resolved persona; canonical home is Discovery/Research/Validation"
|
|
24210
24478
|
}
|
|
24211
24479
|
],
|
|
24212
24480
|
anchor: {
|
|
@@ -24377,6 +24645,14 @@ var UPG_REGIONS = [
|
|
|
24377
24645
|
role: "hub",
|
|
24378
24646
|
notes: "self-nesting"
|
|
24379
24647
|
},
|
|
24648
|
+
{
|
|
24649
|
+
type: "experiment_plan",
|
|
24650
|
+
role: "container"
|
|
24651
|
+
},
|
|
24652
|
+
{
|
|
24653
|
+
type: "experiment_run",
|
|
24654
|
+
role: "container"
|
|
24655
|
+
},
|
|
24380
24656
|
{
|
|
24381
24657
|
type: "learning",
|
|
24382
24658
|
role: "leaf"
|
|
@@ -24546,10 +24822,6 @@ var UPG_REGIONS = [
|
|
|
24546
24822
|
type: "competitive_analysis",
|
|
24547
24823
|
role: "container"
|
|
24548
24824
|
},
|
|
24549
|
-
{
|
|
24550
|
-
type: "territory",
|
|
24551
|
-
role: "leaf"
|
|
24552
|
-
},
|
|
24553
24825
|
{
|
|
24554
24826
|
type: "classification_axis",
|
|
24555
24827
|
role: "container",
|
|
@@ -24569,7 +24841,7 @@ var UPG_REGIONS = [
|
|
|
24569
24841
|
},
|
|
24570
24842
|
intra_edges: [
|
|
24571
24843
|
"competitor_offers_competitor_feature",
|
|
24572
|
-
"
|
|
24844
|
+
"competitive_analysis_analyses_competitor",
|
|
24573
24845
|
"competitive_analysis_dimensioned_by_classification_axis",
|
|
24574
24846
|
"classification_axis_includes_classification_value",
|
|
24575
24847
|
"competitor_classified_as_classification_value"
|
|
@@ -24670,6 +24942,10 @@ var UPG_REGIONS = [
|
|
|
24670
24942
|
type: "screen",
|
|
24671
24943
|
role: "leaf"
|
|
24672
24944
|
},
|
|
24945
|
+
{
|
|
24946
|
+
type: "screen_state",
|
|
24947
|
+
role: "leaf"
|
|
24948
|
+
},
|
|
24673
24949
|
{
|
|
24674
24950
|
type: "wireframe",
|
|
24675
24951
|
role: "leaf"
|
|
@@ -24747,6 +25023,18 @@ var UPG_REGIONS = [
|
|
|
24747
25023
|
type: "content_piece",
|
|
24748
25024
|
role: "leaf"
|
|
24749
25025
|
},
|
|
25026
|
+
{
|
|
25027
|
+
type: "knowledge_base_article",
|
|
25028
|
+
role: "leaf"
|
|
25029
|
+
},
|
|
25030
|
+
{
|
|
25031
|
+
type: "content_calendar",
|
|
25032
|
+
role: "container"
|
|
25033
|
+
},
|
|
25034
|
+
{
|
|
25035
|
+
type: "documentation_template",
|
|
25036
|
+
role: "leaf"
|
|
25037
|
+
},
|
|
24750
25038
|
{
|
|
24751
25039
|
type: "document",
|
|
24752
25040
|
role: "leaf"
|
|
@@ -24765,13 +25053,13 @@ var UPG_REGIONS = [
|
|
|
24765
25053
|
intra_edges: [
|
|
24766
25054
|
"user_journey_contains_journey_step",
|
|
24767
25055
|
"design_system_contains_design_component",
|
|
24768
|
-
"
|
|
24769
|
-
"
|
|
25056
|
+
"brand_identity_coloured_with_brand_colour",
|
|
25057
|
+
"design_component_composes_design_component"
|
|
24770
25058
|
],
|
|
24771
25059
|
boundary_edges: [
|
|
24772
25060
|
{
|
|
24773
25061
|
direction: "import",
|
|
24774
|
-
edge_id: "
|
|
25062
|
+
edge_id: "need_reframed_as_design_question",
|
|
24775
25063
|
crosses_into: "users_needs"
|
|
24776
25064
|
},
|
|
24777
25065
|
{
|
|
@@ -24795,8 +25083,8 @@ var UPG_REGIONS = [
|
|
|
24795
25083
|
crosses_into: "engineering_platform"
|
|
24796
25084
|
},
|
|
24797
25085
|
{
|
|
24798
|
-
direction: "
|
|
24799
|
-
edge_id: "
|
|
25086
|
+
direction: "export",
|
|
25087
|
+
edge_id: "wireframe_specifies_feature",
|
|
24800
25088
|
crosses_into: "product_delivery"
|
|
24801
25089
|
},
|
|
24802
25090
|
{
|
|
@@ -24871,20 +25159,68 @@ var UPG_REGIONS = [
|
|
|
24871
25159
|
role: "container",
|
|
24872
25160
|
notes: "semantic spanner, not containment"
|
|
24873
25161
|
},
|
|
25162
|
+
{
|
|
25163
|
+
type: "changelog",
|
|
25164
|
+
role: "leaf"
|
|
25165
|
+
},
|
|
25166
|
+
{
|
|
25167
|
+
type: "feedback_program",
|
|
25168
|
+
role: "container"
|
|
25169
|
+
},
|
|
25170
|
+
{
|
|
25171
|
+
type: "feature_request",
|
|
25172
|
+
role: "leaf"
|
|
25173
|
+
},
|
|
25174
|
+
{
|
|
25175
|
+
type: "feedback_vote",
|
|
25176
|
+
role: "leaf"
|
|
25177
|
+
},
|
|
25178
|
+
{
|
|
25179
|
+
type: "nps_campaign",
|
|
25180
|
+
role: "leaf"
|
|
25181
|
+
},
|
|
25182
|
+
{
|
|
25183
|
+
type: "user_advisory_board",
|
|
25184
|
+
role: "container"
|
|
25185
|
+
},
|
|
25186
|
+
{
|
|
25187
|
+
type: "beta_program",
|
|
25188
|
+
role: "leaf"
|
|
25189
|
+
},
|
|
25190
|
+
{
|
|
25191
|
+
type: "feedback_theme",
|
|
25192
|
+
role: "leaf"
|
|
25193
|
+
},
|
|
25194
|
+
{
|
|
25195
|
+
type: "program",
|
|
25196
|
+
role: "container"
|
|
25197
|
+
},
|
|
25198
|
+
{
|
|
25199
|
+
type: "project",
|
|
25200
|
+
role: "container"
|
|
25201
|
+
},
|
|
24874
25202
|
{
|
|
24875
25203
|
type: "milestone",
|
|
25204
|
+
role: "leaf"
|
|
25205
|
+
},
|
|
25206
|
+
{
|
|
25207
|
+
type: "risk_register",
|
|
24876
25208
|
role: "container"
|
|
24877
25209
|
},
|
|
24878
25210
|
{
|
|
24879
|
-
type: "
|
|
25211
|
+
type: "change_request",
|
|
24880
25212
|
role: "leaf"
|
|
24881
25213
|
},
|
|
24882
25214
|
{
|
|
24883
|
-
type: "
|
|
25215
|
+
type: "deliverable",
|
|
24884
25216
|
role: "leaf"
|
|
24885
25217
|
},
|
|
24886
25218
|
{
|
|
24887
|
-
type: "
|
|
25219
|
+
type: "resource_allocation",
|
|
25220
|
+
role: "leaf"
|
|
25221
|
+
},
|
|
25222
|
+
{
|
|
25223
|
+
type: "status_report",
|
|
24888
25224
|
role: "leaf"
|
|
24889
25225
|
}
|
|
24890
25226
|
],
|
|
@@ -24953,8 +25289,8 @@ var UPG_REGIONS = [
|
|
|
24953
25289
|
crosses_into: "discovery_research_validation"
|
|
24954
25290
|
},
|
|
24955
25291
|
{
|
|
24956
|
-
direction: "
|
|
24957
|
-
edge_id: "
|
|
25292
|
+
direction: "import",
|
|
25293
|
+
edge_id: "wireframe_specifies_feature",
|
|
24958
25294
|
crosses_into: "experience_design_brand"
|
|
24959
25295
|
},
|
|
24960
25296
|
{
|
|
@@ -25017,10 +25353,6 @@ var UPG_REGIONS = [
|
|
|
25017
25353
|
type: "database_schema",
|
|
25018
25354
|
role: "leaf"
|
|
25019
25355
|
},
|
|
25020
|
-
{
|
|
25021
|
-
type: "data_model",
|
|
25022
|
-
role: "leaf"
|
|
25023
|
-
},
|
|
25024
25356
|
{
|
|
25025
25357
|
type: "aggregate",
|
|
25026
25358
|
role: "container"
|
|
@@ -25085,6 +25417,111 @@ var UPG_REGIONS = [
|
|
|
25085
25417
|
{
|
|
25086
25418
|
type: "technical_debt_item",
|
|
25087
25419
|
role: "leaf"
|
|
25420
|
+
},
|
|
25421
|
+
{
|
|
25422
|
+
type: "investigation",
|
|
25423
|
+
role: "container"
|
|
25424
|
+
},
|
|
25425
|
+
{
|
|
25426
|
+
type: "root_cause",
|
|
25427
|
+
role: "container"
|
|
25428
|
+
},
|
|
25429
|
+
{
|
|
25430
|
+
type: "symptom",
|
|
25431
|
+
role: "leaf"
|
|
25432
|
+
},
|
|
25433
|
+
{
|
|
25434
|
+
type: "fix",
|
|
25435
|
+
role: "leaf"
|
|
25436
|
+
},
|
|
25437
|
+
{
|
|
25438
|
+
type: "ai_model",
|
|
25439
|
+
role: "container"
|
|
25440
|
+
},
|
|
25441
|
+
{
|
|
25442
|
+
type: "prompt_template",
|
|
25443
|
+
role: "leaf"
|
|
25444
|
+
},
|
|
25445
|
+
{
|
|
25446
|
+
type: "prompt_version",
|
|
25447
|
+
role: "leaf"
|
|
25448
|
+
},
|
|
25449
|
+
{
|
|
25450
|
+
type: "eval_benchmark",
|
|
25451
|
+
role: "container"
|
|
25452
|
+
},
|
|
25453
|
+
{
|
|
25454
|
+
type: "eval_run",
|
|
25455
|
+
role: "leaf"
|
|
25456
|
+
},
|
|
25457
|
+
{
|
|
25458
|
+
type: "ai_cost_tracker",
|
|
25459
|
+
role: "leaf"
|
|
25460
|
+
},
|
|
25461
|
+
{
|
|
25462
|
+
type: "hallucination_report",
|
|
25463
|
+
role: "leaf"
|
|
25464
|
+
},
|
|
25465
|
+
{
|
|
25466
|
+
type: "ai_guardrail",
|
|
25467
|
+
role: "leaf"
|
|
25468
|
+
},
|
|
25469
|
+
{
|
|
25470
|
+
type: "model_comparison",
|
|
25471
|
+
role: "leaf"
|
|
25472
|
+
},
|
|
25473
|
+
{
|
|
25474
|
+
type: "ai_experiment",
|
|
25475
|
+
role: "leaf"
|
|
25476
|
+
},
|
|
25477
|
+
{
|
|
25478
|
+
type: "ai_dataset",
|
|
25479
|
+
role: "leaf"
|
|
25480
|
+
},
|
|
25481
|
+
{
|
|
25482
|
+
type: "ai_trace",
|
|
25483
|
+
role: "container",
|
|
25484
|
+
notes: "self-nesting inference chain"
|
|
25485
|
+
},
|
|
25486
|
+
{
|
|
25487
|
+
type: "workflow_template",
|
|
25488
|
+
role: "container"
|
|
25489
|
+
},
|
|
25490
|
+
{
|
|
25491
|
+
type: "workflow_run",
|
|
25492
|
+
role: "container"
|
|
25493
|
+
},
|
|
25494
|
+
{
|
|
25495
|
+
type: "workflow_artifact",
|
|
25496
|
+
role: "leaf"
|
|
25497
|
+
},
|
|
25498
|
+
{
|
|
25499
|
+
type: "agent_definition",
|
|
25500
|
+
role: "container"
|
|
25501
|
+
},
|
|
25502
|
+
{
|
|
25503
|
+
type: "agent_session",
|
|
25504
|
+
role: "leaf"
|
|
25505
|
+
},
|
|
25506
|
+
{
|
|
25507
|
+
type: "agent_skill",
|
|
25508
|
+
role: "leaf"
|
|
25509
|
+
},
|
|
25510
|
+
{
|
|
25511
|
+
type: "agent_hook",
|
|
25512
|
+
role: "leaf"
|
|
25513
|
+
},
|
|
25514
|
+
{
|
|
25515
|
+
type: "agent_task",
|
|
25516
|
+
role: "leaf"
|
|
25517
|
+
},
|
|
25518
|
+
{
|
|
25519
|
+
type: "review_gate",
|
|
25520
|
+
role: "container"
|
|
25521
|
+
},
|
|
25522
|
+
{
|
|
25523
|
+
type: "approval_record",
|
|
25524
|
+
role: "leaf"
|
|
25088
25525
|
}
|
|
25089
25526
|
],
|
|
25090
25527
|
anchor: {
|
|
@@ -25103,7 +25540,7 @@ var UPG_REGIONS = [
|
|
|
25103
25540
|
"service_depends_on_library_dependency",
|
|
25104
25541
|
"service_carries_technical_debt_item",
|
|
25105
25542
|
"service_toggles_feature_flag",
|
|
25106
|
-
"
|
|
25543
|
+
"service_affected_by_root_cause",
|
|
25107
25544
|
"service_investigated_via_investigation"
|
|
25108
25545
|
],
|
|
25109
25546
|
boundary_edges: [
|
|
@@ -25187,6 +25624,26 @@ var UPG_REGIONS = [
|
|
|
25187
25624
|
type: "unit_economics",
|
|
25188
25625
|
role: "leaf"
|
|
25189
25626
|
},
|
|
25627
|
+
{
|
|
25628
|
+
type: "partnership",
|
|
25629
|
+
role: "leaf"
|
|
25630
|
+
},
|
|
25631
|
+
{
|
|
25632
|
+
type: "key_resource",
|
|
25633
|
+
role: "leaf"
|
|
25634
|
+
},
|
|
25635
|
+
{
|
|
25636
|
+
type: "key_activity",
|
|
25637
|
+
role: "leaf"
|
|
25638
|
+
},
|
|
25639
|
+
{
|
|
25640
|
+
type: "customer_relationship",
|
|
25641
|
+
role: "leaf"
|
|
25642
|
+
},
|
|
25643
|
+
{
|
|
25644
|
+
type: "distribution_channel",
|
|
25645
|
+
role: "leaf"
|
|
25646
|
+
},
|
|
25190
25647
|
{
|
|
25191
25648
|
type: "pricing_strategy",
|
|
25192
25649
|
role: "root"
|
|
@@ -25195,6 +25652,18 @@ var UPG_REGIONS = [
|
|
|
25195
25652
|
type: "pricing_tier",
|
|
25196
25653
|
role: "leaf"
|
|
25197
25654
|
},
|
|
25655
|
+
{
|
|
25656
|
+
type: "discount_strategy",
|
|
25657
|
+
role: "leaf"
|
|
25658
|
+
},
|
|
25659
|
+
{
|
|
25660
|
+
type: "trial_config",
|
|
25661
|
+
role: "leaf"
|
|
25662
|
+
},
|
|
25663
|
+
{
|
|
25664
|
+
type: "paywall",
|
|
25665
|
+
role: "leaf"
|
|
25666
|
+
},
|
|
25198
25667
|
{
|
|
25199
25668
|
type: "gtm_strategy",
|
|
25200
25669
|
role: "root"
|
|
@@ -25211,10 +25680,30 @@ var UPG_REGIONS = [
|
|
|
25211
25680
|
type: "messaging",
|
|
25212
25681
|
role: "leaf"
|
|
25213
25682
|
},
|
|
25683
|
+
{
|
|
25684
|
+
type: "content_strategy",
|
|
25685
|
+
role: "container"
|
|
25686
|
+
},
|
|
25687
|
+
{
|
|
25688
|
+
type: "sales_motion",
|
|
25689
|
+
role: "leaf"
|
|
25690
|
+
},
|
|
25691
|
+
{
|
|
25692
|
+
type: "demand_gen_program",
|
|
25693
|
+
role: "leaf"
|
|
25694
|
+
},
|
|
25695
|
+
{
|
|
25696
|
+
type: "territory",
|
|
25697
|
+
role: "leaf"
|
|
25698
|
+
},
|
|
25214
25699
|
{
|
|
25215
25700
|
type: "objection",
|
|
25216
25701
|
role: "leaf"
|
|
25217
25702
|
},
|
|
25703
|
+
{
|
|
25704
|
+
type: "rebuttal",
|
|
25705
|
+
role: "container"
|
|
25706
|
+
},
|
|
25218
25707
|
{
|
|
25219
25708
|
type: "proof_point",
|
|
25220
25709
|
role: "leaf"
|
|
@@ -25262,6 +25751,114 @@ var UPG_REGIONS = [
|
|
|
25262
25751
|
{
|
|
25263
25752
|
type: "variant",
|
|
25264
25753
|
role: "leaf"
|
|
25754
|
+
},
|
|
25755
|
+
{
|
|
25756
|
+
type: "account",
|
|
25757
|
+
role: "container"
|
|
25758
|
+
},
|
|
25759
|
+
{
|
|
25760
|
+
type: "contact",
|
|
25761
|
+
role: "leaf"
|
|
25762
|
+
},
|
|
25763
|
+
{
|
|
25764
|
+
type: "lead",
|
|
25765
|
+
role: "leaf"
|
|
25766
|
+
},
|
|
25767
|
+
{
|
|
25768
|
+
type: "deal",
|
|
25769
|
+
role: "container"
|
|
25770
|
+
},
|
|
25771
|
+
{
|
|
25772
|
+
type: "pipeline_sales",
|
|
25773
|
+
role: "container"
|
|
25774
|
+
},
|
|
25775
|
+
{
|
|
25776
|
+
type: "pipeline_stage",
|
|
25777
|
+
role: "leaf"
|
|
25778
|
+
},
|
|
25779
|
+
{
|
|
25780
|
+
type: "quote_document",
|
|
25781
|
+
role: "leaf"
|
|
25782
|
+
},
|
|
25783
|
+
{
|
|
25784
|
+
type: "subscription",
|
|
25785
|
+
role: "container"
|
|
25786
|
+
},
|
|
25787
|
+
{
|
|
25788
|
+
type: "invoice",
|
|
25789
|
+
role: "leaf"
|
|
25790
|
+
},
|
|
25791
|
+
{
|
|
25792
|
+
type: "forecast",
|
|
25793
|
+
role: "leaf"
|
|
25794
|
+
},
|
|
25795
|
+
{
|
|
25796
|
+
type: "marketing_strategy",
|
|
25797
|
+
role: "container"
|
|
25798
|
+
},
|
|
25799
|
+
{
|
|
25800
|
+
type: "marketing_channel",
|
|
25801
|
+
role: "container"
|
|
25802
|
+
},
|
|
25803
|
+
{
|
|
25804
|
+
type: "marketing_campaign_plan",
|
|
25805
|
+
role: "container"
|
|
25806
|
+
},
|
|
25807
|
+
{
|
|
25808
|
+
type: "email_sequence",
|
|
25809
|
+
role: "leaf"
|
|
25810
|
+
},
|
|
25811
|
+
{
|
|
25812
|
+
type: "social_post",
|
|
25813
|
+
role: "leaf"
|
|
25814
|
+
},
|
|
25815
|
+
{
|
|
25816
|
+
type: "seo_keyword",
|
|
25817
|
+
role: "leaf"
|
|
25818
|
+
},
|
|
25819
|
+
{
|
|
25820
|
+
type: "ad_creative",
|
|
25821
|
+
role: "leaf"
|
|
25822
|
+
},
|
|
25823
|
+
{
|
|
25824
|
+
type: "press_release",
|
|
25825
|
+
role: "leaf"
|
|
25826
|
+
},
|
|
25827
|
+
{
|
|
25828
|
+
type: "event",
|
|
25829
|
+
role: "leaf"
|
|
25830
|
+
},
|
|
25831
|
+
{
|
|
25832
|
+
type: "community_initiative",
|
|
25833
|
+
role: "leaf"
|
|
25834
|
+
},
|
|
25835
|
+
{
|
|
25836
|
+
type: "partner_program",
|
|
25837
|
+
role: "container"
|
|
25838
|
+
},
|
|
25839
|
+
{
|
|
25840
|
+
type: "partner_tier",
|
|
25841
|
+
role: "leaf"
|
|
25842
|
+
},
|
|
25843
|
+
{
|
|
25844
|
+
type: "api_ecosystem",
|
|
25845
|
+
role: "container"
|
|
25846
|
+
},
|
|
25847
|
+
{
|
|
25848
|
+
type: "marketplace_listing",
|
|
25849
|
+
role: "leaf"
|
|
25850
|
+
},
|
|
25851
|
+
{
|
|
25852
|
+
type: "developer_portal",
|
|
25853
|
+
role: "leaf"
|
|
25854
|
+
},
|
|
25855
|
+
{
|
|
25856
|
+
type: "integration_partner",
|
|
25857
|
+
role: "leaf"
|
|
25858
|
+
},
|
|
25859
|
+
{
|
|
25860
|
+
type: "partner_revenue_share",
|
|
25861
|
+
role: "leaf"
|
|
25265
25862
|
}
|
|
25266
25863
|
],
|
|
25267
25864
|
anchor: {
|
|
@@ -25368,7 +25965,8 @@ var UPG_REGIONS = [
|
|
|
25368
25965
|
entities: [
|
|
25369
25966
|
{
|
|
25370
25967
|
type: "metric",
|
|
25371
|
-
role: "anchor"
|
|
25968
|
+
role: "anchor",
|
|
25969
|
+
notes: "canonical home is Strategy; anchors Analytics as the measurement plane"
|
|
25372
25970
|
},
|
|
25373
25971
|
{
|
|
25374
25972
|
type: "data_source",
|
|
@@ -25382,24 +25980,36 @@ var UPG_REGIONS = [
|
|
|
25382
25980
|
type: "dashboard",
|
|
25383
25981
|
role: "container"
|
|
25384
25982
|
},
|
|
25983
|
+
{
|
|
25984
|
+
type: "data_model",
|
|
25985
|
+
role: "leaf"
|
|
25986
|
+
},
|
|
25385
25987
|
{
|
|
25386
25988
|
type: "data_domain",
|
|
25387
25989
|
role: "container"
|
|
25388
25990
|
},
|
|
25389
25991
|
{
|
|
25390
|
-
type: "
|
|
25992
|
+
type: "data_product",
|
|
25391
25993
|
role: "leaf"
|
|
25392
25994
|
},
|
|
25393
25995
|
{
|
|
25394
|
-
type: "
|
|
25996
|
+
type: "data_pipeline",
|
|
25395
25997
|
role: "leaf"
|
|
25396
25998
|
},
|
|
25397
25999
|
{
|
|
25398
|
-
type: "
|
|
26000
|
+
type: "data_lineage",
|
|
25399
26001
|
role: "leaf"
|
|
25400
26002
|
},
|
|
25401
26003
|
{
|
|
25402
|
-
type: "
|
|
26004
|
+
type: "glossary_term",
|
|
26005
|
+
role: "leaf"
|
|
26006
|
+
},
|
|
26007
|
+
{
|
|
26008
|
+
type: "report",
|
|
26009
|
+
role: "leaf"
|
|
26010
|
+
},
|
|
26011
|
+
{
|
|
26012
|
+
type: "data_quality_rule",
|
|
25403
26013
|
role: "leaf"
|
|
25404
26014
|
}
|
|
25405
26015
|
],
|
|
@@ -25525,7 +26135,27 @@ var UPG_REGIONS = [
|
|
|
25525
26135
|
{
|
|
25526
26136
|
type: "deployment",
|
|
25527
26137
|
role: "leaf",
|
|
25528
|
-
notes: "
|
|
26138
|
+
notes: "canonical home is Engineering; release event surfaced to Ops"
|
|
26139
|
+
},
|
|
26140
|
+
{
|
|
26141
|
+
type: "alert_rule",
|
|
26142
|
+
role: "leaf"
|
|
26143
|
+
},
|
|
26144
|
+
{
|
|
26145
|
+
type: "ci_pipeline",
|
|
26146
|
+
role: "container"
|
|
26147
|
+
},
|
|
26148
|
+
{
|
|
26149
|
+
type: "release_strategy",
|
|
26150
|
+
role: "leaf"
|
|
26151
|
+
},
|
|
26152
|
+
{
|
|
26153
|
+
type: "on_call_rotation",
|
|
26154
|
+
role: "leaf"
|
|
26155
|
+
},
|
|
26156
|
+
{
|
|
26157
|
+
type: "infrastructure_component",
|
|
26158
|
+
role: "container"
|
|
25529
26159
|
},
|
|
25530
26160
|
{
|
|
25531
26161
|
type: "test_suite",
|
|
@@ -25543,10 +26173,26 @@ var UPG_REGIONS = [
|
|
|
25543
26173
|
type: "test_result",
|
|
25544
26174
|
role: "leaf"
|
|
25545
26175
|
},
|
|
26176
|
+
{
|
|
26177
|
+
type: "regression_test",
|
|
26178
|
+
role: "leaf"
|
|
26179
|
+
},
|
|
26180
|
+
{
|
|
26181
|
+
type: "test_coverage_report",
|
|
26182
|
+
role: "leaf"
|
|
26183
|
+
},
|
|
26184
|
+
{
|
|
26185
|
+
type: "test_environment",
|
|
26186
|
+
role: "leaf"
|
|
26187
|
+
},
|
|
25546
26188
|
{
|
|
25547
26189
|
type: "threat_model",
|
|
25548
26190
|
role: "root"
|
|
25549
26191
|
},
|
|
26192
|
+
{
|
|
26193
|
+
type: "threat",
|
|
26194
|
+
role: "leaf"
|
|
26195
|
+
},
|
|
25550
26196
|
{
|
|
25551
26197
|
type: "security_control",
|
|
25552
26198
|
role: "leaf"
|
|
@@ -25563,14 +26209,34 @@ var UPG_REGIONS = [
|
|
|
25563
26209
|
type: "penetration_test",
|
|
25564
26210
|
role: "leaf"
|
|
25565
26211
|
},
|
|
26212
|
+
{
|
|
26213
|
+
type: "security_review",
|
|
26214
|
+
role: "container"
|
|
26215
|
+
},
|
|
26216
|
+
{
|
|
26217
|
+
type: "data_classification",
|
|
26218
|
+
role: "leaf"
|
|
26219
|
+
},
|
|
26220
|
+
{
|
|
26221
|
+
type: "access_policy",
|
|
26222
|
+
role: "leaf"
|
|
26223
|
+
},
|
|
25566
26224
|
{
|
|
25567
26225
|
type: "a11y_standard",
|
|
25568
26226
|
role: "leaf"
|
|
25569
26227
|
},
|
|
26228
|
+
{
|
|
26229
|
+
type: "a11y_guideline",
|
|
26230
|
+
role: "leaf"
|
|
26231
|
+
},
|
|
25570
26232
|
{
|
|
25571
26233
|
type: "a11y_audit",
|
|
25572
26234
|
role: "leaf"
|
|
25573
26235
|
},
|
|
26236
|
+
{
|
|
26237
|
+
type: "a11y_issue",
|
|
26238
|
+
role: "leaf"
|
|
26239
|
+
},
|
|
25574
26240
|
{
|
|
25575
26241
|
type: "a11y_annotation",
|
|
25576
26242
|
role: "leaf"
|
|
@@ -25588,11 +26254,15 @@ var UPG_REGIONS = [
|
|
|
25588
26254
|
role: "leaf"
|
|
25589
26255
|
},
|
|
25590
26256
|
{
|
|
25591
|
-
type: "
|
|
26257
|
+
type: "data_contract",
|
|
25592
26258
|
role: "leaf"
|
|
25593
26259
|
},
|
|
25594
26260
|
{
|
|
25595
|
-
type: "
|
|
26261
|
+
type: "audit_log_policy",
|
|
26262
|
+
role: "leaf"
|
|
26263
|
+
},
|
|
26264
|
+
{
|
|
26265
|
+
type: "security_audit",
|
|
25596
26266
|
role: "leaf"
|
|
25597
26267
|
},
|
|
25598
26268
|
{
|
|
@@ -25621,16 +26291,16 @@ var UPG_REGIONS = [
|
|
|
25621
26291
|
role: "root"
|
|
25622
26292
|
},
|
|
25623
26293
|
{
|
|
25624
|
-
type: "
|
|
26294
|
+
type: "customer_journey_stage",
|
|
25625
26295
|
role: "container"
|
|
25626
26296
|
},
|
|
25627
26297
|
{
|
|
25628
|
-
type: "
|
|
25629
|
-
role: "
|
|
26298
|
+
type: "touchpoint",
|
|
26299
|
+
role: "leaf"
|
|
25630
26300
|
},
|
|
25631
26301
|
{
|
|
25632
|
-
type: "
|
|
25633
|
-
role: "
|
|
26302
|
+
type: "success_milestone",
|
|
26303
|
+
role: "leaf"
|
|
25634
26304
|
},
|
|
25635
26305
|
{
|
|
25636
26306
|
type: "team",
|
|
@@ -25644,6 +26314,10 @@ var UPG_REGIONS = [
|
|
|
25644
26314
|
type: "role",
|
|
25645
26315
|
role: "leaf"
|
|
25646
26316
|
},
|
|
26317
|
+
{
|
|
26318
|
+
type: "person",
|
|
26319
|
+
role: "leaf"
|
|
26320
|
+
},
|
|
25647
26321
|
{
|
|
25648
26322
|
type: "stakeholder",
|
|
25649
26323
|
role: "leaf",
|
|
@@ -25671,6 +26345,78 @@ var UPG_REGIONS = [
|
|
|
25671
26345
|
},
|
|
25672
26346
|
{
|
|
25673
26347
|
type: "capacity_plan",
|
|
26348
|
+
role: "leaf"
|
|
26349
|
+
},
|
|
26350
|
+
{
|
|
26351
|
+
type: "legal_entity",
|
|
26352
|
+
role: "container"
|
|
26353
|
+
},
|
|
26354
|
+
{
|
|
26355
|
+
type: "ip_asset",
|
|
26356
|
+
role: "leaf"
|
|
26357
|
+
},
|
|
26358
|
+
{
|
|
26359
|
+
type: "contract",
|
|
26360
|
+
role: "container"
|
|
26361
|
+
},
|
|
26362
|
+
{
|
|
26363
|
+
type: "contract_clause",
|
|
26364
|
+
role: "leaf"
|
|
26365
|
+
},
|
|
26366
|
+
{
|
|
26367
|
+
type: "privacy_policy",
|
|
26368
|
+
role: "leaf"
|
|
26369
|
+
},
|
|
26370
|
+
{
|
|
26371
|
+
type: "locale",
|
|
26372
|
+
role: "container"
|
|
26373
|
+
},
|
|
26374
|
+
{
|
|
26375
|
+
type: "translation_key",
|
|
26376
|
+
role: "leaf"
|
|
26377
|
+
},
|
|
26378
|
+
{
|
|
26379
|
+
type: "translation_bundle",
|
|
26380
|
+
role: "container"
|
|
26381
|
+
},
|
|
26382
|
+
{
|
|
26383
|
+
type: "locale_config",
|
|
26384
|
+
role: "leaf"
|
|
26385
|
+
},
|
|
26386
|
+
{
|
|
26387
|
+
type: "cultural_adaptation",
|
|
26388
|
+
role: "leaf"
|
|
26389
|
+
},
|
|
26390
|
+
{
|
|
26391
|
+
type: "regional_pricing",
|
|
26392
|
+
role: "leaf"
|
|
26393
|
+
},
|
|
26394
|
+
{
|
|
26395
|
+
type: "education_program",
|
|
26396
|
+
role: "container"
|
|
26397
|
+
},
|
|
26398
|
+
{
|
|
26399
|
+
type: "tutorial",
|
|
26400
|
+
role: "leaf"
|
|
26401
|
+
},
|
|
26402
|
+
{
|
|
26403
|
+
type: "walkthrough",
|
|
26404
|
+
role: "leaf"
|
|
26405
|
+
},
|
|
26406
|
+
{
|
|
26407
|
+
type: "webinar",
|
|
26408
|
+
role: "leaf"
|
|
26409
|
+
},
|
|
26410
|
+
{
|
|
26411
|
+
type: "certification",
|
|
26412
|
+
role: "leaf"
|
|
26413
|
+
},
|
|
26414
|
+
{
|
|
26415
|
+
type: "help_video",
|
|
26416
|
+
role: "leaf"
|
|
26417
|
+
},
|
|
26418
|
+
{
|
|
26419
|
+
type: "learning_path",
|
|
25674
26420
|
role: "container"
|
|
25675
26421
|
}
|
|
25676
26422
|
],
|
|
@@ -25687,7 +26433,6 @@ var UPG_REGIONS = [
|
|
|
25687
26433
|
"incident_analysed_in_postmortem",
|
|
25688
26434
|
"incident_triggers_postmortem",
|
|
25689
26435
|
"incident_breaches_service_level_objective",
|
|
25690
|
-
"incident_caused_by_root_cause",
|
|
25691
26436
|
"incident_exploits_vulnerability"
|
|
25692
26437
|
],
|
|
25693
26438
|
boundary_edges: [
|
|
@@ -25708,8 +26453,8 @@ var UPG_REGIONS = [
|
|
|
25708
26453
|
},
|
|
25709
26454
|
{
|
|
25710
26455
|
direction: "export",
|
|
25711
|
-
edge_id: "
|
|
25712
|
-
crosses_into: "
|
|
26456
|
+
edge_id: "incident_caused_by_root_cause",
|
|
26457
|
+
crosses_into: "engineering_platform"
|
|
25713
26458
|
},
|
|
25714
26459
|
{
|
|
25715
26460
|
direction: "export",
|
|
@@ -26105,7 +26850,16 @@ function portfolioBody(doc) {
|
|
|
26105
26850
|
product_areas: [...doc.product_areas ?? []].sort((a, b) => byCodeUnit(a.id ?? "", b.id ?? "")).map((a) => orderedObject(a, ["id", "title", "description", "parent_area_id", "strategic_priority", "products"], { forceKeys: ["id", "title"] })),
|
|
26106
26851
|
portfolios: [...doc.portfolios ?? []].sort((a, b) => byCodeUnit(a.id ?? "", b.id ?? "")).map((p) => orderedObject(p, ["id", "title", "description", "parent_portfolio_id", "hierarchy_model", "products"], { forceKeys: ["id", "title"] })),
|
|
26107
26852
|
products,
|
|
26108
|
-
cross_edges: sortEdges(doc.cross_edges ?? []).map(canonicalCrossEdge)
|
|
26853
|
+
cross_edges: sortEdges(doc.cross_edges ?? []).map(canonicalCrossEdge),
|
|
26854
|
+
// Registry tier (shared vocabulary). Emitted only when non-empty so existing
|
|
26855
|
+
// portfolio files without a registry stay byte-identical. Canonical entities
|
|
26856
|
+
// are normal nodes, serialised with the same node/edge canonical rules.
|
|
26857
|
+
...doc.registry && doc.registry.nodes.length > 0 ? {
|
|
26858
|
+
registry: {
|
|
26859
|
+
nodes: sortNodes(doc.registry.nodes).map(canonicalNode),
|
|
26860
|
+
...doc.registry.edges && doc.registry.edges.length > 0 ? { edges: sortEdges(doc.registry.edges).map(canonicalEdge) } : {}
|
|
26861
|
+
}
|
|
26862
|
+
} : {}
|
|
26109
26863
|
};
|
|
26110
26864
|
}
|
|
26111
26865
|
function computeBodyChecksum(doc) {
|
|
@@ -26205,6 +26959,13 @@ function normalizeDocument(obj) {
|
|
|
26205
26959
|
})),
|
|
26206
26960
|
cross_edges: raw.cross_edges ?? []
|
|
26207
26961
|
};
|
|
26962
|
+
const rawRegistry = raw.registry;
|
|
26963
|
+
if (rawRegistry && Array.isArray(rawRegistry.nodes)) {
|
|
26964
|
+
out2.registry = {
|
|
26965
|
+
nodes: rawRegistry.nodes.map((n) => repairNodeDrift(n)),
|
|
26966
|
+
...Array.isArray(rawRegistry.edges) ? { edges: rawRegistry.edges } : {}
|
|
26967
|
+
};
|
|
26968
|
+
}
|
|
26208
26969
|
return out2;
|
|
26209
26970
|
}
|
|
26210
26971
|
const out = {
|
|
@@ -26227,7 +26988,7 @@ function isCanonical(text) {
|
|
|
26227
26988
|
}
|
|
26228
26989
|
|
|
26229
26990
|
// src/index.ts
|
|
26230
|
-
var UPG_VERSION = "0.9.
|
|
26991
|
+
var UPG_VERSION = "0.9.7";
|
|
26231
26992
|
var UPG_FORMAT_VERSION = "0.4.0";
|
|
26232
26993
|
var MARKDOWN_FORMAT_VERSION = "0.1";
|
|
26233
26994
|
var UPG_TYPES = getTypes();
|
|
@@ -26307,6 +27068,7 @@ var UPG_META_COUNT = UPG_ENTITY_META.length;
|
|
|
26307
27068
|
PRODUCT_DELIVERY_PLAYBOOK,
|
|
26308
27069
|
PROPERTY_SCALE_MAP,
|
|
26309
27070
|
REFLECT_MODES,
|
|
27071
|
+
REGISTRY_PRODUCT_ID,
|
|
26310
27072
|
STRATEGY_OUTCOMES_PLAYBOOK,
|
|
26311
27073
|
UPG_ACTIVE_TYPES,
|
|
26312
27074
|
UPG_ANTI_PATTERNS,
|