create_cross_product_edge
Create a cross-product relationship between two entities in different products within a portfolio graph. Types: `shares_persona`, `shares_competitor`, `shares_metric`, `depends_on_product`, `cannibalises`, `succeeds`, `hosts` (host product runs the hosted product inside itself, directed host to hosted), `contributes_to` (a product strategy entity rolls up to a higher-level one, e.g. product objective → company objective; directed subordinate to superior), `rolls_up_to` (a product metric feeds a company/portfolio metric, e.g. a product KPI → a company north-star; directed feeder to feed, same-type metric → metric). For `instance_of` use `register_instance`; for `area_serves_persona` / `area_targets_market_segment` use `link_area_to_audience`.
Arguments
source_idstringrequiredSource node ID
target_idstringrequiredTarget node ID
typestringrequiredCross-product relationship type
source_product_idstringoptionalProduct ID of the source node
target_product_idstringoptionalProduct ID of the target node
propertiesobjectoptionalEdge metadata, accepted only for cross-edge types declared carries_properties (e.g. feature_rivals_competitor_feature, carrying the parity assessment parity_status / quality / is_gap / assessed_on / evidence / confidence). Rejected for types that do not carry properties.
dry_runbooleanoptionalForecast the write without mutating: returns { dry_run: true, would: create | update | unchanged, edge } and writes nothing. Use to reason about a write before running it.
supersedebooleanoptionalClassification edges only. When a classify write moves a source to a new value on a single-select axis, retire the prior same-axis edge (default true) so the source carries one current value. Set false to keep both (additive). A multi-select axis always keeps both.
Returns
{ edge, portfolio_file }