@unified-product-graph/core 0.9.6 → 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/dist/index.cjs CHANGED
@@ -707,7 +707,9 @@ var UPG_ENTITY_META = [
707
707
  { name: "objective", type_id: "ent_004", maturity: "stable", since: "0.1.0" },
708
708
  { name: "key_result", type_id: "ent_005", maturity: "stable", since: "0.1.0" },
709
709
  { name: "metric", type_id: "ent_006", maturity: "stable", since: "0.1.0" },
710
- { name: "metric_quality_assessment", type_id: "ent_339", maturity: "proposed", since: "0.2.2" },
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" },
711
713
  { name: "vision", type_id: "ent_007", maturity: "stable", since: "0.1.0" },
712
714
  { name: "mission", type_id: "ent_008", maturity: "stable", since: "0.1.0" },
713
715
  { name: "strategic_theme", type_id: "ent_009", maturity: "stable", since: "0.1.0" },
@@ -764,8 +766,11 @@ var UPG_ENTITY_META = [
764
766
  { name: "market_segment", type_id: "ent_036", maturity: "stable", since: "0.1.0" },
765
767
  { name: "competitive_analysis", type_id: "ent_037", maturity: "stable", since: "0.1.0" },
766
768
  // Classification taxonomy hosted by competitive_analysis.
767
- { name: "classification_axis", type_id: "ent_346", maturity: "proposed", since: "0.4.0" },
768
- { name: "classification_value", type_id: "ent_347", maturity: "proposed", since: "0.4.0" },
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" },
769
774
  // ── UX Research ──
770
775
  { name: "research_study", type_id: "ent_038", maturity: "stable", since: "0.1.0" },
771
776
  { name: "research_insight", type_id: "ent_039", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "insight" },
@@ -805,8 +810,10 @@ var UPG_ENTITY_META = [
805
810
  { name: "journey_phase", type_id: "ent_330", maturity: "proposed", since: "0.2.0" },
806
811
  { name: "journey_action", type_id: "ent_331", maturity: "proposed", since: "0.2.0" },
807
812
  { name: "design_decision", type_id: "ent_319", maturity: "deprecated", since: "0.2.0", deprecated_in: "0.2.0", replacement: "decision" },
808
- { name: "brand_logo", type_id: "ent_321", maturity: "proposed", since: "0.2.0" },
809
- { name: "brand_imagery", type_id: "ent_322", maturity: "proposed", since: "0.2.0" },
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" },
810
817
  // ── Product Spec ──
811
818
  { name: "feature_area", type_id: "ent_314", maturity: "stable", since: "0.1.0" },
812
819
  { name: "feature", type_id: "ent_071", maturity: "stable", since: "0.1.0" },
@@ -822,6 +829,15 @@ var UPG_ENTITY_META = [
822
829
  // alias. `story_task` (the original work half) was already collapsed into
823
830
  // canonical `task` at v0.4.0. So the canonical shape is: user_story (statement)
824
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.
825
841
  { name: "user_story", type_id: "ent_073", maturity: "proposed", since: "0.1.0" },
826
842
  { name: "story_statement", type_id: "ent_342", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.7.0", replacement: "user_story" },
827
843
  { name: "story_task", type_id: "ent_343", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.4.0", replacement: "task" },
@@ -1838,8 +1854,11 @@ var UPG_EDGE_CATALOG = {
1838
1854
  value_proposition_targets_persona_cross_domain: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "value_proposition", target_type: "persona" },
1839
1855
  revenue_stream_drives_metric: { forward_verb: "drives", reverse_verb: "driven_by", classification: "cross-domain", source_type: "revenue_stream", target_type: "metric" },
1840
1856
  // Ring 5 structural edges
1841
- funnel_step_maps_to_journey_step: { forward_verb: "maps_to", reverse_verb: "mapped_by", classification: "cross-domain", source_type: "funnel", target_type: "journey_step" },
1842
- customer_journey_stage_contains_funnel_step: { forward_verb: "contains", reverse_verb: "contained_in", classification: "cross-domain", source_type: "customer_journey_stage", target_type: "funnel" },
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" },
1843
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" },
1844
1863
  dependency_blocks_team: { forward_verb: "blocks", reverse_verb: "blocked_by", classification: "cross-domain", source_type: "dependency", target_type: "team" },
1845
1864
  dependency_depends_on_team: { forward_verb: "depends_on", reverse_verb: "depended_on_by", classification: "cross-domain", source_type: "dependency", target_type: "team" },
@@ -1892,7 +1911,7 @@ var UPG_EDGE_CATALOG = {
1892
1911
  positioning_within_market_segment: { forward_verb: "within", reverse_verb: "positioned_by", classification: "cross-domain", source_type: "positioning", target_type: "market_segment" },
1893
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" },
1894
1913
  launch_amplified_by_marketing_channel: { forward_verb: "amplified_by", reverse_verb: "amplifies", classification: "cross-domain", source_type: "launch", target_type: "marketing_channel" },
1895
- sales_motion_qualifies_via_funnel_step: { forward_verb: "qualifies_via", reverse_verb: "qualifies_for", classification: "cross-domain", source_type: "sales_motion", target_type: "funnel" },
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" },
1896
1915
  objection_sourced_from_quote: { forward_verb: "sourced_from", reverse_verb: "surfaced_objection", classification: "cross-domain", source_type: "objection", target_type: "quote" },
1897
1916
  proof_point_derived_from_evidence: { forward_verb: "derived_from", reverse_verb: "evidences", classification: "cross-domain", source_type: "proof_point", target_type: "evidence" },
1898
1917
  proof_point_derived_from_insight: { forward_verb: "derived_from", reverse_verb: "evidences", classification: "cross-domain", source_type: "proof_point", target_type: "insight" },
@@ -2906,7 +2925,104 @@ var UPG_EDGE_CATALOG = {
2906
2925
  // to `journey_step_reveals_need` (existing); both express "what
2907
2926
  // research surfaces at this step". Useful for any journey-based
2908
2927
  // research method (CX mapping, service blueprint, behavioural cohort).
2909
- 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" }
2910
3026
  };
2911
3027
  var UPG_POLYMORPHIC_EDGE_KEYS = [
2912
3028
  // Universal semantic verbs
@@ -3255,7 +3371,11 @@ var UPG_VALID_CHILDREN = {
3255
3371
  "survey_response"
3256
3372
  ],
3257
3373
  observation: ["quote"],
3258
- affinity_cluster: ["insight"],
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"],
3259
3379
  // insight refines into insight; a raw insight can be distilled
3260
3380
  // into a more specific insight (refines_into chain).
3261
3381
  // v0.5.8 (UPG-528 Part 2d): insights own their evidencing quotes;
@@ -10473,6 +10593,7 @@ var UPG_PROPERTY_SCHEMA = {
10473
10593
  },
10474
10594
  // LearningPathProperties: Learning path.
10475
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." },
10476
10597
  path_difficulty: { type: "string", enum: ["beginner", "intermediate", "advanced"], description: "Overall difficulty level of the learning path" },
10477
10598
  item_count: { type: "number", description: "Number of items (tutorials, videos, etc.) in the path" },
10478
10599
  estimated_hours: { type: "number", description: "Estimated total hours to complete the path" },
@@ -10622,6 +10743,7 @@ var UPG_PROPERTY_SCHEMA = {
10622
10743
  },
10623
10744
  // MilestoneProperties: Milestone.
10624
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`." },
10625
10747
  due_date: { type: "string", description: "Target due date (ISO format)" },
10626
10748
  met_on_time: { type: "boolean", description: "Whether the milestone was met on time" }
10627
10749
  },
@@ -10826,6 +10948,7 @@ var UPG_PROPERTY_SCHEMA = {
10826
10948
  },
10827
10949
  // PartnerTierProperties: Partner tier.
10828
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." },
10829
10952
  tier_level: { type: "number", description: "Numeric rank of the tier (higher = more prestigious)" },
10830
10953
  requirements: { type: "string[]", description: "What a partner must achieve to reach this tier" },
10831
10954
  benefits: { type: "string[]", description: "Benefits granted at this tier level" }
@@ -11248,6 +11371,7 @@ var UPG_PROPERTY_SCHEMA = {
11248
11371
  },
11249
11372
  // ScreenStateProperties: Specific state of a screen.
11250
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)." },
11251
11375
  state_name: { type: "string", enum: ["empty", "loading", "error", "populated", "skeleton", "partial"], description: "State" },
11252
11376
  trigger: { type: "string", description: "Cause for entering this state" },
11253
11377
  condition: { type: "string", description: "Data or environmental condition the state represents" },
@@ -11760,6 +11884,7 @@ var UPG_PROPERTY_SCHEMA = {
11760
11884
  },
11761
11885
  // UserFlowProperties: User flow.
11762
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." },
11763
11888
  trigger: { type: "string", description: "Initiating event" },
11764
11889
  steps: { type: "string[]", description: "Ordered steps" },
11765
11890
  success_state: { type: "string", description: "Successful completion" },
@@ -17823,7 +17948,10 @@ var PRIORITY_LABELS = [
17823
17948
  {
17824
17949
  id: "solution",
17825
17950
  canonical_label: "Solution",
17826
- alt_labels: ["proposed solution", "solution idea", "concept", "approach"],
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"],
17827
17955
  framework_labels: {
17828
17956
  ost: "Solution",
17829
17957
  design_thinking: "Solution",
@@ -17986,7 +18114,10 @@ var PRIORITY_LABELS = [
17986
18114
  {
17987
18115
  id: "outcome",
17988
18116
  canonical_label: "Outcome",
17989
- alt_labels: ["desired outcome", "product outcome", "business outcome", "target outcome"],
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"],
17990
18121
  framework_labels: {
17991
18122
  ost: "Desired Outcome",
17992
18123
  okr_tree: "Outcome"
@@ -18014,7 +18145,10 @@ var PRIORITY_LABELS = [
18014
18145
  {
18015
18146
  id: "feature",
18016
18147
  canonical_label: "Feature",
18017
- alt_labels: ["capability", "product feature", "functionality"],
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"],
18018
18152
  framework_labels: {
18019
18153
  rice: "Scored Item",
18020
18154
  moscow: "Prioritised Item",
@@ -18085,7 +18219,10 @@ var PRIORITY_LABELS = [
18085
18219
  {
18086
18220
  id: "distribution_channel",
18087
18221
  canonical_label: "Distribution Channel",
18088
- alt_labels: ["channel", "sales channel", "delivery channel", "distribution"],
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"],
18089
18226
  framework_labels: {
18090
18227
  bmc: "Channel",
18091
18228
  lean_canvas: "Channel"
@@ -18265,7 +18402,8 @@ var PRIORITY_LABELS = [
18265
18402
  ];
18266
18403
  var STANDARD_LABELS = {
18267
18404
  // Strategic layer
18268
- product: { alt_labels: ["offering", "app", "service", "platform"] },
18405
+ // 'service' stripped (P-B / UPG-670): canonical label of the distinct `service` type.
18406
+ product: { alt_labels: ["offering", "app", "platform"] },
18269
18407
  vision: { alt_labels: ["product vision", "north star vision", "long-term vision"] },
18270
18408
  mission: { alt_labels: ["mission statement", "purpose"] },
18271
18409
  strategic_theme: { alt_labels: ["focus area", "strategic focus area"] },
@@ -18283,7 +18421,8 @@ var STANDARD_LABELS = {
18283
18421
  design_sprint: { alt_labels: ["sprint", "gv sprint", "google ventures sprint"] },
18284
18422
  // Validation layer
18285
18423
  learning: { alt_labels: ["validated learning", "lesson learned", "takeaway"] },
18286
- test_plan: { alt_labels: ["experiment plan", "validation plan"] },
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"] },
18287
18426
  research_plan: { alt_labels: ["study plan", "research brief"] },
18288
18427
  evidence: { alt_labels: ["proof", "supporting data", "signal"] },
18289
18428
  variant: { alt_labels: ["test variant", "experiment arm", "variation"] },
@@ -18291,7 +18430,9 @@ var STANDARD_LABELS = {
18291
18430
  competitor: { alt_labels: ["rival", "alternative", "competitive product", "competing product"] },
18292
18431
  competitor_feature: { alt_labels: ["competitive feature", "rival capability"] },
18293
18432
  market_trend: { alt_labels: ["trend", "industry trend", "macro trend"] },
18294
- market_segment: { alt_labels: ["segment", "market slice", "tam segment", "sam segment"] },
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"] },
18295
18436
  competitive_analysis: { alt_labels: ["competitor analysis", "competitive landscape", "market analysis"] },
18296
18437
  // UX Research layer
18297
18438
  research_study: { alt_labels: ["study", "user study", "research project", "ux study"] },
@@ -18327,7 +18468,8 @@ var STANDARD_LABELS = {
18327
18468
  brand_typography: { alt_labels: ["typeface", "font family", "type system"] },
18328
18469
  brand_voice: { alt_labels: ["tone of voice", "brand tone", "writing style"] },
18329
18470
  // Product Specification layer
18330
- epic: { alt_labels: ["initiative", "large story", "feature set"] },
18471
+ // 'initiative' stripped (P-B / UPG-670): canonical label of the distinct `initiative` type.
18472
+ epic: { alt_labels: ["large story", "feature set"] },
18331
18473
  feature_area: { alt_labels: ["feature group", "capability area", "module"] },
18332
18474
  acceptance_criterion: { alt_labels: ["ac", "done criterion", "acceptance criteria", "definition of done"] },
18333
18475
  release: { alt_labels: ["version", "ship", "launch version", "build"] },
@@ -18341,8 +18483,10 @@ var STANDARD_LABELS = {
18341
18483
  // Engineering layer
18342
18484
  bounded_context: { alt_labels: ["context", "domain boundary", "module boundary"] },
18343
18485
  service: { alt_labels: ["microservice", "backend service", "api service"] },
18344
- domain_event: { alt_labels: ["event", "system event", "business event"] },
18345
- api_contract: { alt_labels: ["api spec", "api schema", "contract", "openapi spec"] },
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"] },
18346
18490
  technical_debt_item: { alt_labels: ["tech debt", "debt", "tech debt item", "cleanup"] },
18347
18491
  feature_flag: { alt_labels: ["flag", "toggle", "feature toggle", "release flag"] },
18348
18492
  aggregate: { alt_labels: ["aggregate root", "ddd aggregate"] },
@@ -18355,15 +18499,19 @@ var STANDARD_LABELS = {
18355
18499
  queue_topic: { alt_labels: ["topic", "message queue", "event bus topic", "pubsub topic"] },
18356
18500
  build_artifact: { alt_labels: ["artifact", "binary", "docker image", "package"] },
18357
18501
  code_repository: { alt_labels: ["repo", "repository", "git repo", "codebase"] },
18358
- library_dependency: { alt_labels: ["dependency", "package", "library", "npm package"] },
18502
+ // 'dependency' stripped (P-B / UPG-670): canonical label of the distinct `dependency` type.
18503
+ library_dependency: { alt_labels: ["package", "library", "npm package"] },
18359
18504
  integration_pattern: { alt_labels: ["integration", "pattern", "middleware pattern"] },
18360
18505
  external_api: { alt_labels: ["third-party api", "vendor api", "saas integration"] },
18361
18506
  data_flow: { alt_labels: ["data movement", "data transfer", "pipeline flow"] },
18362
18507
  // Growth layer
18363
- acquisition_channel: { alt_labels: ["channel", "traffic source", "user source"] },
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"] },
18364
18510
  growth_campaign: { alt_labels: ["campaign", "marketing campaign", "ad campaign", "growth campaign"] },
18365
18511
  cohort: { alt_labels: ["user cohort", "retention cohort", "signup cohort"] },
18366
- behavioral_segment: { alt_labels: ["segment", "user segment", "audience segment", "behavioural segment"] },
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"] },
18367
18515
  growth_loop: { alt_labels: ["viral loop", "referral loop", "flywheel"] },
18368
18516
  attribution_model: { alt_labels: ["attribution", "marketing attribution", "channel attribution"] },
18369
18517
  // Business Model layer
@@ -18392,7 +18540,8 @@ var STANDARD_LABELS = {
18392
18540
  retrospective: { alt_labels: ["retro", "sprint retro", "team retro", "post-mortem"] },
18393
18541
  dependency: { alt_labels: ["team dependency", "cross-team dependency", "blocker"] },
18394
18542
  department: { alt_labels: ["org unit", "division", "business unit"] },
18395
- skill: { alt_labels: ["competency", "capability", "expertise"] },
18543
+ // 'capability' stripped (P-B / UPG-670): canonical label of the distinct `capability` type.
18544
+ skill: { alt_labels: ["competency", "expertise"] },
18396
18545
  ceremony: { alt_labels: ["ritual", "meeting cadence", "standup", "retrospective meeting"] },
18397
18546
  capacity_plan: { alt_labels: ["resourcing plan", "staffing plan", "headcount plan"] },
18398
18547
  // Data & Analytics layer
@@ -18402,7 +18551,8 @@ var STANDARD_LABELS = {
18402
18551
  data_model: { alt_labels: ["erd", "entity relationship diagram", "schema model"] },
18403
18552
  data_quality_rule: { alt_labels: ["data rule", "quality check", "data validation"] },
18404
18553
  data_product: { alt_labels: ["data asset", "data offering"] },
18405
- data_pipeline: { alt_labels: ["etl", "elt", "ingestion pipeline", "data flow"] },
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"] },
18406
18556
  data_lineage: { alt_labels: ["lineage", "data provenance", "data trail"] },
18407
18557
  glossary_term: { alt_labels: ["term", "definition", "business term"] },
18408
18558
  data_domain: { alt_labels: ["data area", "data subject area"] },
@@ -18444,7 +18594,8 @@ var STANDARD_LABELS = {
18444
18594
  error_budget: { alt_labels: ["reliability budget", "downtime budget"] },
18445
18595
  investigation: { alt_labels: ["incident investigation", "root cause analysis", "debugging"] },
18446
18596
  postmortem: { alt_labels: ["post-mortem", "incident review", "rca", "root cause analysis"] },
18447
- runbook: { alt_labels: ["operations guide", "playbook", "sop", "standard operating procedure"] },
18597
+ // 'playbook' stripped (P-B / UPG-670): canonical label of the distinct `playbook` type.
18598
+ runbook: { alt_labels: ["operations guide", "sop", "standard operating procedure"] },
18448
18599
  monitor: { alt_labels: ["health check", "synthetic monitor", "uptime check"] },
18449
18600
  alert_rule: { alt_labels: ["alert", "pager rule", "notification rule"] },
18450
18601
  release_strategy: { alt_labels: ["rollout strategy", "deployment strategy", "canary release"] },
@@ -18459,17 +18610,26 @@ var STANDARD_LABELS = {
18459
18610
  security_control: { alt_labels: ["control", "safeguard", "countermeasure", "mitigation"] },
18460
18611
  security_policy: { alt_labels: ["infosec policy", "security standard"] },
18461
18612
  penetration_test: { alt_labels: ["pentest", "pen test", "security test"] },
18462
- security_review: { alt_labels: ["code review", "security assessment", "audit"] },
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"] },
18463
18617
  data_classification: { alt_labels: ["classification", "sensitivity level", "data label"] },
18464
18618
  access_policy: { alt_labels: ["iam policy", "rbac rule", "permission", "access control"] },
18465
18619
  // Sales & Revenue layer
18466
- account: { alt_labels: ["customer account", "client", "organization"] },
18467
- contact: { alt_labels: ["person", "buyer", "champion"] },
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"] },
18468
18624
  lead: { alt_labels: ["prospect", "mql", "sql", "marketing lead"] },
18469
- deal: { alt_labels: ["opportunity", "sales opportunity", "opp"] },
18625
+ // 'opportunity' stripped (P-B / UPG-670): canonical label of the distinct `opportunity` (OST) type.
18626
+ deal: { alt_labels: ["sales opportunity", "opp"] },
18470
18627
  pipeline_sales: { alt_labels: ["sales pipeline", "deal pipeline", "revenue pipeline"] },
18471
18628
  pipeline_stage: { alt_labels: ["deal stage", "sales stage"] },
18472
- quote_document: { alt_labels: ["quote", "proposal", "estimate", "quotation"] },
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"] },
18473
18633
  subscription: { alt_labels: ["recurring revenue", "saas subscription", "plan"] },
18474
18634
  invoice: { alt_labels: ["bill", "payment request"] },
18475
18635
  forecast: { alt_labels: ["revenue forecast", "sales forecast", "projection"] },
@@ -18490,7 +18650,8 @@ var STANDARD_LABELS = {
18490
18650
  a11y_annotation: { alt_labels: ["accessibility annotation", "aria note"] },
18491
18651
  // Marketing & Communications layer
18492
18652
  marketing_strategy: { alt_labels: ["marketing plan", "growth strategy"] },
18493
- marketing_channel: { alt_labels: ["channel", "paid channel", "organic channel"] },
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"] },
18494
18655
  marketing_campaign_plan: { alt_labels: ["campaign plan", "launch campaign"] },
18495
18656
  email_sequence: { alt_labels: ["drip campaign", "nurture sequence", "email flow"] },
18496
18657
  social_post: { alt_labels: ["tweet", "linkedin post", "social media post"] },
@@ -18564,7 +18725,9 @@ var STANDARD_LABELS = {
18564
18725
  agent_session: { alt_labels: ["session", "agent run", "agent conversation"] },
18565
18726
  review_gate: { alt_labels: ["approval gate", "quality gate", "stage gate"] },
18566
18727
  approval_record: { alt_labels: ["approval", "sign-off", "authorization"] },
18567
- agent_skill: { alt_labels: ["skill", "tool", "agent capability"] },
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"] },
18568
18731
  agent_hook: { alt_labels: ["hook", "trigger", "callback"] },
18569
18732
  workflow_artifact: { alt_labels: ["artifact", "output artifact", "generated artifact"] },
18570
18733
  // Portfolio layer
@@ -23708,6 +23871,96 @@ var UPG_ANTI_PATTERNS = [
23708
23871
  stages: ["concept", "validation", "build", "beta", "launch", "growth"],
23709
23872
  severity: "high",
23710
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)" }
23711
23964
  }
23712
23965
  ];
23713
23966
  function getAntiPatternById(id) {
@@ -24046,6 +24299,10 @@ var UPG_REGIONS = [
24046
24299
  "strategy"
24047
24300
  ],
24048
24301
  entities: [
24302
+ {
24303
+ type: "product",
24304
+ role: "container"
24305
+ },
24049
24306
  {
24050
24307
  type: "vision",
24051
24308
  role: "root"
@@ -24085,7 +24342,11 @@ var UPG_REGIONS = [
24085
24342
  {
24086
24343
  type: "metric",
24087
24344
  role: "leaf",
24088
- notes: "shared with Analytics"
24345
+ notes: "also anchors Analytics; canonical home is Strategy"
24346
+ },
24347
+ {
24348
+ type: "metric_quality_assessment",
24349
+ role: "leaf"
24089
24350
  },
24090
24351
  {
24091
24352
  type: "decision",
@@ -24096,6 +24357,10 @@ var UPG_REGIONS = [
24096
24357
  type: "assumption",
24097
24358
  role: "leaf"
24098
24359
  },
24360
+ {
24361
+ type: "constraint",
24362
+ role: "leaf"
24363
+ },
24099
24364
  {
24100
24365
  type: "outcome",
24101
24366
  role: "hub"
@@ -24209,7 +24474,7 @@ var UPG_REGIONS = [
24209
24474
  {
24210
24475
  type: "participant",
24211
24476
  role: "leaf",
24212
- notes: "research-resolved persona"
24477
+ notes: "research-resolved persona; canonical home is Discovery/Research/Validation"
24213
24478
  }
24214
24479
  ],
24215
24480
  anchor: {
@@ -24380,6 +24645,14 @@ var UPG_REGIONS = [
24380
24645
  role: "hub",
24381
24646
  notes: "self-nesting"
24382
24647
  },
24648
+ {
24649
+ type: "experiment_plan",
24650
+ role: "container"
24651
+ },
24652
+ {
24653
+ type: "experiment_run",
24654
+ role: "container"
24655
+ },
24383
24656
  {
24384
24657
  type: "learning",
24385
24658
  role: "leaf"
@@ -24549,10 +24822,6 @@ var UPG_REGIONS = [
24549
24822
  type: "competitive_analysis",
24550
24823
  role: "container"
24551
24824
  },
24552
- {
24553
- type: "territory",
24554
- role: "leaf"
24555
- },
24556
24825
  {
24557
24826
  type: "classification_axis",
24558
24827
  role: "container",
@@ -24572,7 +24841,7 @@ var UPG_REGIONS = [
24572
24841
  },
24573
24842
  intra_edges: [
24574
24843
  "competitor_offers_competitor_feature",
24575
- "competitive_analysis_contains_competitor",
24844
+ "competitive_analysis_analyses_competitor",
24576
24845
  "competitive_analysis_dimensioned_by_classification_axis",
24577
24846
  "classification_axis_includes_classification_value",
24578
24847
  "competitor_classified_as_classification_value"
@@ -24673,6 +24942,10 @@ var UPG_REGIONS = [
24673
24942
  type: "screen",
24674
24943
  role: "leaf"
24675
24944
  },
24945
+ {
24946
+ type: "screen_state",
24947
+ role: "leaf"
24948
+ },
24676
24949
  {
24677
24950
  type: "wireframe",
24678
24951
  role: "leaf"
@@ -24750,6 +25023,18 @@ var UPG_REGIONS = [
24750
25023
  type: "content_piece",
24751
25024
  role: "leaf"
24752
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
+ },
24753
25038
  {
24754
25039
  type: "document",
24755
25040
  role: "leaf"
@@ -24768,13 +25053,13 @@ var UPG_REGIONS = [
24768
25053
  intra_edges: [
24769
25054
  "user_journey_contains_journey_step",
24770
25055
  "design_system_contains_design_component",
24771
- "brand_identity_contains_brand_colour",
24772
- "design_component_self_nests"
25056
+ "brand_identity_coloured_with_brand_colour",
25057
+ "design_component_composes_design_component"
24773
25058
  ],
24774
25059
  boundary_edges: [
24775
25060
  {
24776
25061
  direction: "import",
24777
- edge_id: "need_informs_design_question",
25062
+ edge_id: "need_reframed_as_design_question",
24778
25063
  crosses_into: "users_needs"
24779
25064
  },
24780
25065
  {
@@ -24798,8 +25083,8 @@ var UPG_REGIONS = [
24798
25083
  crosses_into: "engineering_platform"
24799
25084
  },
24800
25085
  {
24801
- direction: "sideways",
24802
- edge_id: "feature_sketched_in_wireframe",
25086
+ direction: "export",
25087
+ edge_id: "wireframe_specifies_feature",
24803
25088
  crosses_into: "product_delivery"
24804
25089
  },
24805
25090
  {
@@ -24874,20 +25159,68 @@ var UPG_REGIONS = [
24874
25159
  role: "container",
24875
25160
  notes: "semantic spanner, not containment"
24876
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
+ },
24877
25202
  {
24878
25203
  type: "milestone",
25204
+ role: "leaf"
25205
+ },
25206
+ {
25207
+ type: "risk_register",
24879
25208
  role: "container"
24880
25209
  },
24881
25210
  {
24882
- type: "changelog",
25211
+ type: "change_request",
24883
25212
  role: "leaf"
24884
25213
  },
24885
25214
  {
24886
- type: "feature_request",
25215
+ type: "deliverable",
24887
25216
  role: "leaf"
24888
25217
  },
24889
25218
  {
24890
- type: "feedback_vote",
25219
+ type: "resource_allocation",
25220
+ role: "leaf"
25221
+ },
25222
+ {
25223
+ type: "status_report",
24891
25224
  role: "leaf"
24892
25225
  }
24893
25226
  ],
@@ -24956,8 +25289,8 @@ var UPG_REGIONS = [
24956
25289
  crosses_into: "discovery_research_validation"
24957
25290
  },
24958
25291
  {
24959
- direction: "sideways",
24960
- edge_id: "feature_sketched_in_wireframe",
25292
+ direction: "import",
25293
+ edge_id: "wireframe_specifies_feature",
24961
25294
  crosses_into: "experience_design_brand"
24962
25295
  },
24963
25296
  {
@@ -25020,10 +25353,6 @@ var UPG_REGIONS = [
25020
25353
  type: "database_schema",
25021
25354
  role: "leaf"
25022
25355
  },
25023
- {
25024
- type: "data_model",
25025
- role: "leaf"
25026
- },
25027
25356
  {
25028
25357
  type: "aggregate",
25029
25358
  role: "container"
@@ -25088,6 +25417,111 @@ var UPG_REGIONS = [
25088
25417
  {
25089
25418
  type: "technical_debt_item",
25090
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"
25091
25525
  }
25092
25526
  ],
25093
25527
  anchor: {
@@ -25106,7 +25540,7 @@ var UPG_REGIONS = [
25106
25540
  "service_depends_on_library_dependency",
25107
25541
  "service_carries_technical_debt_item",
25108
25542
  "service_toggles_feature_flag",
25109
- "service_caused_by_root_cause",
25543
+ "service_affected_by_root_cause",
25110
25544
  "service_investigated_via_investigation"
25111
25545
  ],
25112
25546
  boundary_edges: [
@@ -25190,6 +25624,26 @@ var UPG_REGIONS = [
25190
25624
  type: "unit_economics",
25191
25625
  role: "leaf"
25192
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
+ },
25193
25647
  {
25194
25648
  type: "pricing_strategy",
25195
25649
  role: "root"
@@ -25198,6 +25652,18 @@ var UPG_REGIONS = [
25198
25652
  type: "pricing_tier",
25199
25653
  role: "leaf"
25200
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
+ },
25201
25667
  {
25202
25668
  type: "gtm_strategy",
25203
25669
  role: "root"
@@ -25214,10 +25680,30 @@ var UPG_REGIONS = [
25214
25680
  type: "messaging",
25215
25681
  role: "leaf"
25216
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
+ },
25217
25699
  {
25218
25700
  type: "objection",
25219
25701
  role: "leaf"
25220
25702
  },
25703
+ {
25704
+ type: "rebuttal",
25705
+ role: "container"
25706
+ },
25221
25707
  {
25222
25708
  type: "proof_point",
25223
25709
  role: "leaf"
@@ -25265,6 +25751,114 @@ var UPG_REGIONS = [
25265
25751
  {
25266
25752
  type: "variant",
25267
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"
25268
25862
  }
25269
25863
  ],
25270
25864
  anchor: {
@@ -25371,7 +25965,8 @@ var UPG_REGIONS = [
25371
25965
  entities: [
25372
25966
  {
25373
25967
  type: "metric",
25374
- role: "anchor"
25968
+ role: "anchor",
25969
+ notes: "canonical home is Strategy; anchors Analytics as the measurement plane"
25375
25970
  },
25376
25971
  {
25377
25972
  type: "data_source",
@@ -25385,24 +25980,36 @@ var UPG_REGIONS = [
25385
25980
  type: "dashboard",
25386
25981
  role: "container"
25387
25982
  },
25983
+ {
25984
+ type: "data_model",
25985
+ role: "leaf"
25986
+ },
25388
25987
  {
25389
25988
  type: "data_domain",
25390
25989
  role: "container"
25391
25990
  },
25392
25991
  {
25393
- type: "glossary_term",
25992
+ type: "data_product",
25394
25993
  role: "leaf"
25395
25994
  },
25396
25995
  {
25397
- type: "forecast",
25996
+ type: "data_pipeline",
25398
25997
  role: "leaf"
25399
25998
  },
25400
25999
  {
25401
- type: "data_quality_rule",
26000
+ type: "data_lineage",
25402
26001
  role: "leaf"
25403
26002
  },
25404
26003
  {
25405
- type: "data_contract",
26004
+ type: "glossary_term",
26005
+ role: "leaf"
26006
+ },
26007
+ {
26008
+ type: "report",
26009
+ role: "leaf"
26010
+ },
26011
+ {
26012
+ type: "data_quality_rule",
25406
26013
  role: "leaf"
25407
26014
  }
25408
26015
  ],
@@ -25528,7 +26135,27 @@ var UPG_REGIONS = [
25528
26135
  {
25529
26136
  type: "deployment",
25530
26137
  role: "leaf",
25531
- notes: "shared with Engineering"
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"
25532
26159
  },
25533
26160
  {
25534
26161
  type: "test_suite",
@@ -25546,10 +26173,26 @@ var UPG_REGIONS = [
25546
26173
  type: "test_result",
25547
26174
  role: "leaf"
25548
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
+ },
25549
26188
  {
25550
26189
  type: "threat_model",
25551
26190
  role: "root"
25552
26191
  },
26192
+ {
26193
+ type: "threat",
26194
+ role: "leaf"
26195
+ },
25553
26196
  {
25554
26197
  type: "security_control",
25555
26198
  role: "leaf"
@@ -25566,14 +26209,34 @@ var UPG_REGIONS = [
25566
26209
  type: "penetration_test",
25567
26210
  role: "leaf"
25568
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
+ },
25569
26224
  {
25570
26225
  type: "a11y_standard",
25571
26226
  role: "leaf"
25572
26227
  },
26228
+ {
26229
+ type: "a11y_guideline",
26230
+ role: "leaf"
26231
+ },
25573
26232
  {
25574
26233
  type: "a11y_audit",
25575
26234
  role: "leaf"
25576
26235
  },
26236
+ {
26237
+ type: "a11y_issue",
26238
+ role: "leaf"
26239
+ },
25577
26240
  {
25578
26241
  type: "a11y_annotation",
25579
26242
  role: "leaf"
@@ -25591,11 +26254,15 @@ var UPG_REGIONS = [
25591
26254
  role: "leaf"
25592
26255
  },
25593
26256
  {
25594
- type: "root_cause",
26257
+ type: "data_contract",
25595
26258
  role: "leaf"
25596
26259
  },
25597
26260
  {
25598
- type: "investigation",
26261
+ type: "audit_log_policy",
26262
+ role: "leaf"
26263
+ },
26264
+ {
26265
+ type: "security_audit",
25599
26266
  role: "leaf"
25600
26267
  },
25601
26268
  {
@@ -25624,16 +26291,16 @@ var UPG_REGIONS = [
25624
26291
  role: "root"
25625
26292
  },
25626
26293
  {
25627
- type: "beta_program",
26294
+ type: "customer_journey_stage",
25628
26295
  role: "container"
25629
26296
  },
25630
26297
  {
25631
- type: "feedback_program",
25632
- role: "container"
26298
+ type: "touchpoint",
26299
+ role: "leaf"
25633
26300
  },
25634
26301
  {
25635
- type: "user_advisory_board",
25636
- role: "container"
26302
+ type: "success_milestone",
26303
+ role: "leaf"
25637
26304
  },
25638
26305
  {
25639
26306
  type: "team",
@@ -25647,6 +26314,10 @@ var UPG_REGIONS = [
25647
26314
  type: "role",
25648
26315
  role: "leaf"
25649
26316
  },
26317
+ {
26318
+ type: "person",
26319
+ role: "leaf"
26320
+ },
25650
26321
  {
25651
26322
  type: "stakeholder",
25652
26323
  role: "leaf",
@@ -25674,6 +26345,78 @@ var UPG_REGIONS = [
25674
26345
  },
25675
26346
  {
25676
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",
25677
26420
  role: "container"
25678
26421
  }
25679
26422
  ],
@@ -25690,7 +26433,6 @@ var UPG_REGIONS = [
25690
26433
  "incident_analysed_in_postmortem",
25691
26434
  "incident_triggers_postmortem",
25692
26435
  "incident_breaches_service_level_objective",
25693
- "incident_caused_by_root_cause",
25694
26436
  "incident_exploits_vulnerability"
25695
26437
  ],
25696
26438
  boundary_edges: [
@@ -25711,8 +26453,8 @@ var UPG_REGIONS = [
25711
26453
  },
25712
26454
  {
25713
26455
  direction: "export",
25714
- edge_id: "beta_program_runs_experiment",
25715
- crosses_into: "discovery_research_validation"
26456
+ edge_id: "incident_caused_by_root_cause",
26457
+ crosses_into: "engineering_platform"
25716
26458
  },
25717
26459
  {
25718
26460
  direction: "export",
@@ -26246,7 +26988,7 @@ function isCanonical(text) {
26246
26988
  }
26247
26989
 
26248
26990
  // src/index.ts
26249
- var UPG_VERSION = "0.9.6";
26991
+ var UPG_VERSION = "0.9.7";
26250
26992
  var UPG_FORMAT_VERSION = "0.4.0";
26251
26993
  var MARKDOWN_FORMAT_VERSION = "0.1";
26252
26994
  var UPG_TYPES = getTypes();