@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.js CHANGED
@@ -514,7 +514,9 @@ var UPG_ENTITY_META = [
514
514
  { name: "objective", type_id: "ent_004", maturity: "stable", since: "0.1.0" },
515
515
  { name: "key_result", type_id: "ent_005", maturity: "stable", since: "0.1.0" },
516
516
  { name: "metric", type_id: "ent_006", maturity: "stable", since: "0.1.0" },
517
- { name: "metric_quality_assessment", type_id: "ent_339", maturity: "proposed", since: "0.2.2" },
517
+ // F7 (UPG-673): graduated proposed → stable at v0.9.x — proposed since 0.2.2,
518
+ // the metric-quality assessment artefact is settled with no open restructure.
519
+ { name: "metric_quality_assessment", type_id: "ent_339", maturity: "stable", since: "0.2.2" },
518
520
  { name: "vision", type_id: "ent_007", maturity: "stable", since: "0.1.0" },
519
521
  { name: "mission", type_id: "ent_008", maturity: "stable", since: "0.1.0" },
520
522
  { name: "strategic_theme", type_id: "ent_009", maturity: "stable", since: "0.1.0" },
@@ -571,8 +573,11 @@ var UPG_ENTITY_META = [
571
573
  { name: "market_segment", type_id: "ent_036", maturity: "stable", since: "0.1.0" },
572
574
  { name: "competitive_analysis", type_id: "ent_037", maturity: "stable", since: "0.1.0" },
573
575
  // Classification taxonomy hosted by competitive_analysis.
574
- { name: "classification_axis", type_id: "ent_346", maturity: "proposed", since: "0.4.0" },
575
- { name: "classification_value", type_id: "ent_347", maturity: "proposed", since: "0.4.0" },
576
+ // F7 (UPG-673): graduated proposed → stable at v0.9.x — two minor releases
577
+ // stable since 0.4.0, the taxonomy-axis/value pair backs the competitive-
578
+ // analysis classification spine with no open rename/restructure ticket.
579
+ { name: "classification_axis", type_id: "ent_346", maturity: "stable", since: "0.4.0" },
580
+ { name: "classification_value", type_id: "ent_347", maturity: "stable", since: "0.4.0" },
576
581
  // ── UX Research ──
577
582
  { name: "research_study", type_id: "ent_038", maturity: "stable", since: "0.1.0" },
578
583
  { name: "research_insight", type_id: "ent_039", maturity: "deprecated", since: "0.1.0", deprecated_in: "0.1.0", replacement: "insight" },
@@ -612,8 +617,10 @@ var UPG_ENTITY_META = [
612
617
  { name: "journey_phase", type_id: "ent_330", maturity: "proposed", since: "0.2.0" },
613
618
  { name: "journey_action", type_id: "ent_331", maturity: "proposed", since: "0.2.0" },
614
619
  { name: "design_decision", type_id: "ent_319", maturity: "deprecated", since: "0.2.0", deprecated_in: "0.2.0", replacement: "decision" },
615
- { name: "brand_logo", type_id: "ent_321", maturity: "proposed", since: "0.2.0" },
616
- { name: "brand_imagery", type_id: "ent_322", maturity: "proposed", since: "0.2.0" },
620
+ // F7 (UPG-673): graduated proposed → stable at v0.9.x — proposed since 0.2.0,
621
+ // the brand-identity set (logo + imagery) is settled with no open rename.
622
+ { name: "brand_logo", type_id: "ent_321", maturity: "stable", since: "0.2.0" },
623
+ { name: "brand_imagery", type_id: "ent_322", maturity: "stable", since: "0.2.0" },
617
624
  // ── Product Spec ──
618
625
  { name: "feature_area", type_id: "ent_314", maturity: "stable", since: "0.1.0" },
619
626
  { name: "feature", type_id: "ent_071", maturity: "stable", since: "0.1.0" },
@@ -629,6 +636,15 @@ var UPG_ENTITY_META = [
629
636
  // alias. `story_task` (the original work half) was already collapsed into
630
637
  // canonical `task` at v0.4.0. So the canonical shape is: user_story (statement)
631
638
  // + task (work), linked by `task_implements_user_story`.
639
+ //
640
+ // F7 (UPG-673) — DEFERRED, deliberately kept `proposed`. The audit flagged
641
+ // user_story as a stable-spine candidate, but the v0.7.0 re-canon contract
642
+ // (UPG-571) freezes maturity at `proposed` until the re-canonicalised name
643
+ // has soaked across a full migration window. `user-story-split.test.ts`
644
+ // ("user_story is canonical again (ent_073, proposed, not deprecated)")
645
+ // asserts `proposed` as the post-re-canon invariant. Graduating here would
646
+ // break that contract; promotion is a separate, ticketed decision once the
647
+ // story_statement → user_story migration has fully aged out.
632
648
  { name: "user_story", type_id: "ent_073", maturity: "proposed", since: "0.1.0" },
633
649
  { name: "story_statement", type_id: "ent_342", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.7.0", replacement: "user_story" },
634
650
  { name: "story_task", type_id: "ent_343", maturity: "deprecated", since: "0.2.7", deprecated_in: "0.4.0", replacement: "task" },
@@ -1645,8 +1661,11 @@ var UPG_EDGE_CATALOG = {
1645
1661
  value_proposition_targets_persona_cross_domain: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "cross-domain", source_type: "value_proposition", target_type: "persona" },
1646
1662
  revenue_stream_drives_metric: { forward_verb: "drives", reverse_verb: "driven_by", classification: "cross-domain", source_type: "revenue_stream", target_type: "metric" },
1647
1663
  // Ring 5 structural edges
1648
- funnel_step_maps_to_journey_step: { forward_verb: "maps_to", reverse_verb: "mapped_by", classification: "cross-domain", source_type: "funnel", target_type: "journey_step" },
1649
- customer_journey_stage_contains_funnel_step: { forward_verb: "contains", reverse_verb: "contained_in", classification: "cross-domain", source_type: "customer_journey_stage", target_type: "funnel" },
1664
+ // (UPG-668, P-I) These three edges name `funnel_step` but were typed against
1665
+ // `funnel`, so they resolved from the wrong side and were invisible on the
1666
+ // funnel_step card. Repointed to `funnel_step`; keys unchanged.
1667
+ 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" },
1668
+ 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" },
1650
1669
  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" },
1651
1670
  dependency_blocks_team: { forward_verb: "blocks", reverse_verb: "blocked_by", classification: "cross-domain", source_type: "dependency", target_type: "team" },
1652
1671
  dependency_depends_on_team: { forward_verb: "depends_on", reverse_verb: "depended_on_by", classification: "cross-domain", source_type: "dependency", target_type: "team" },
@@ -1699,7 +1718,7 @@ var UPG_EDGE_CATALOG = {
1699
1718
  positioning_within_market_segment: { forward_verb: "within", reverse_verb: "positioned_by", classification: "cross-domain", source_type: "positioning", target_type: "market_segment" },
1700
1719
  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" },
1701
1720
  launch_amplified_by_marketing_channel: { forward_verb: "amplified_by", reverse_verb: "amplifies", classification: "cross-domain", source_type: "launch", target_type: "marketing_channel" },
1702
- sales_motion_qualifies_via_funnel_step: { forward_verb: "qualifies_via", reverse_verb: "qualifies_for", classification: "cross-domain", source_type: "sales_motion", target_type: "funnel" },
1721
+ 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" },
1703
1722
  objection_sourced_from_quote: { forward_verb: "sourced_from", reverse_verb: "surfaced_objection", classification: "cross-domain", source_type: "objection", target_type: "quote" },
1704
1723
  proof_point_derived_from_evidence: { forward_verb: "derived_from", reverse_verb: "evidences", classification: "cross-domain", source_type: "proof_point", target_type: "evidence" },
1705
1724
  proof_point_derived_from_insight: { forward_verb: "derived_from", reverse_verb: "evidences", classification: "cross-domain", source_type: "proof_point", target_type: "insight" },
@@ -2713,7 +2732,104 @@ var UPG_EDGE_CATALOG = {
2713
2732
  // to `journey_step_reveals_need` (existing); both express "what
2714
2733
  // research surfaces at this step". Useful for any journey-based
2715
2734
  // research method (CX mapping, service blueprint, behavioural cohort).
2716
- journey_step_yields_observation: { forward_verb: "yields", reverse_verb: "yielded_in", classification: "cross-domain", source_type: "journey_step", target_type: "observation" }
2735
+ journey_step_yields_observation: { forward_verb: "yields", reverse_verb: "yielded_in", classification: "cross-domain", source_type: "journey_step", target_type: "observation" },
2736
+ // ── Part 11: F6 (UPG-672) dead-end & missing-bridge pass ────────────────────
2737
+ // P-A (scored / synthesis / verdict leaves with 0 outbound) + P-D (missing
2738
+ // forward bridges) from the 36-domain wiring audit. Every edge below closes a
2739
+ // confirmed dead-end or missing direction. Naming respects the F2 prefix gate
2740
+ // (key begins with its `source_type` as a whole token) and the F3 dup gate (no
2741
+ // source→target pair already in the catalog). Verified against the catalog at
2742
+ // build time; see the F6 commit body for the audit ledger references.
2743
+ // ── F6: Priority 1 — both-sides-verified cross-domain bridges ──────────────
2744
+ // data_classification ↔ privacy_policy (security SEC-3/L5 + legal). The
2745
+ // classification leaf reached only data_source; it could not reach the policy
2746
+ // that governs how it must be handled. A privacy_policy GOVERNS a data
2747
+ // classification (sets retention / handling rules for that sensitivity tier).
2748
+ data_classification_governed_by_privacy_policy: { forward_verb: "governed_by", reverse_verb: "governs", classification: "cross-domain", source_type: "data_classification", target_type: "privacy_policy" },
2749
+ // design_component → a11y conformance (design_system DS-3 + accessibility A).
2750
+ // The whole conformance DIRECTION was missing: a11y_issue → design_component
2751
+ // existed (defect points back), but no component → standard/guideline link
2752
+ // expressing "this component CONFORMS TO this rule". Both the testable
2753
+ // standard and the human-readable guideline are valid conformance targets.
2754
+ 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" },
2755
+ 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" },
2756
+ // feature_request → feature ship-closure (feedback + product_spec). A request
2757
+ // could reach an opportunity but never the feature that ships it, so the loop
2758
+ // from "user asked" to "we built it" had no closing edge. A feature_request
2759
+ // BECOMES a feature when the team commits to building it.
2760
+ feature_request_becomes_feature: { forward_verb: "becomes", reverse_verb: "originated_from", classification: "cross-domain", source_type: "feature_request", target_type: "feature" },
2761
+ // objective → outcome (OKR spine). objective reached key_result and metric but
2762
+ // not the outcome it exists to move; the strategic spine was severed at its
2763
+ // anchor (0 outbound to outcome). An objective ADVANCES an outcome. Intra-
2764
+ // domain (both in strategy) and directional → causal.
2765
+ objective_advances_outcome: { forward_verb: "advances", reverse_verb: "advanced_by", classification: "causal", source_type: "objective", target_type: "outcome" },
2766
+ // ── F6: Priority 2 — scored / synthesis / verdict dead-end leaves (P-A) ─────
2767
+ // desired_outcome (Ulwick-scored: importance × satisfaction) had 0 outbound —
2768
+ // the scores could not flow anywhere. An under-served desired_outcome REVEALS
2769
+ // an opportunity, and is QUANTIFIED BY the metric that tracks its satisfaction.
2770
+ desired_outcome_reveals_opportunity: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "desired_outcome", target_type: "opportunity" },
2771
+ desired_outcome_quantified_by_metric: { forward_verb: "quantified_by", reverse_verb: "quantifies", classification: "cross-domain", source_type: "desired_outcome", target_type: "metric" },
2772
+ // feasibility_study + design_sprint: discovery VERDICTS with 0 outbound — they
2773
+ // could not reach the decision, solution, or learning they exist to produce.
2774
+ // A study/sprint INFORMS a decision, RECOMMENDS a solution, and PRODUCES a
2775
+ // learning. solution is intra-discovery (semantic); decision (strategy) and
2776
+ // learning (validation) are cross-domain.
2777
+ feasibility_study_informs_decision: { forward_verb: "informs", reverse_verb: "informed_by", classification: "cross-domain", source_type: "feasibility_study", target_type: "decision" },
2778
+ feasibility_study_recommends_solution: { forward_verb: "recommends", reverse_verb: "recommended_by", classification: "semantic", source_type: "feasibility_study", target_type: "solution" },
2779
+ feasibility_study_produces_learning: { forward_verb: "produces", reverse_verb: "produced_by", classification: "cross-domain", source_type: "feasibility_study", target_type: "learning" },
2780
+ design_sprint_informs_decision: { forward_verb: "informs", reverse_verb: "informed_by", classification: "cross-domain", source_type: "design_sprint", target_type: "decision" },
2781
+ design_sprint_recommends_solution: { forward_verb: "recommends", reverse_verb: "recommended_by", classification: "semantic", source_type: "design_sprint", target_type: "solution" },
2782
+ design_sprint_produces_learning: { forward_verb: "produces", reverse_verb: "produced_by", classification: "cross-domain", source_type: "design_sprint", target_type: "learning" },
2783
+ // affinity_cluster → observation (user_research). A cluster synthesised an
2784
+ // insight but could not OWN the raw observations it groups; the cluster's
2785
+ // membership was unrepresentable. Intra-domain ownership → hierarchy.
2786
+ affinity_cluster_groups_observation: { forward_verb: "groups", reverse_verb: "grouped_in", classification: "hierarchy", source_type: "affinity_cluster", target_type: "observation" },
2787
+ // feedback_theme → opportunity (feedback). A theme validated needs and
2788
+ // surfaced insights but could not point at the opportunity it implies — the
2789
+ // theme could not become actionable discovery input.
2790
+ feedback_theme_reveals_opportunity: { forward_verb: "reveals", reverse_verb: "revealed_by", classification: "cross-domain", source_type: "feedback_theme", target_type: "opportunity" },
2791
+ // competitor_feature → capability (market_intelligence). A competitor feature
2792
+ // inspired our solution/feature but could not map to the capability it
2793
+ // demonstrates — competitive capability benchmarking was unrepresentable.
2794
+ competitor_feature_benchmarks_capability: { forward_verb: "benchmarks", reverse_verb: "benchmarked_by", classification: "cross-domain", source_type: "competitor_feature", target_type: "capability" },
2795
+ // switching_cost → competitor (user). A switching cost is the friction of
2796
+ // leaving an incumbent, but the leaf had 0 outbound — it could not name the
2797
+ // competitor it locks the user into. It LOCKS IN a competitor.
2798
+ switching_cost_locks_in_competitor: { forward_verb: "locks_in", reverse_verb: "locked_in_by", classification: "cross-domain", source_type: "switching_cost", target_type: "competitor" },
2799
+ // ── F6: region tail — confirmed dead-end leaves across remaining domains ────
2800
+ // test_result (testing) had 0 outbound — a failing result could not file the
2801
+ // defect it found. A test_result REPORTS a bug.
2802
+ test_result_reports_bug: { forward_verb: "reports", reverse_verb: "reported_by", classification: "cross-domain", source_type: "test_result", target_type: "bug" },
2803
+ // content_piece → social_post (content → marketing). Content reached messaging
2804
+ // and campaigns but not the social post it is repurposed into — the atomisation
2805
+ // step had no edge.
2806
+ 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" },
2807
+ // translation_key (localisation) had 0 outbound — it could neither reach the
2808
+ // content it localises nor the locale it targets. Both bridges close the leaf.
2809
+ // translation_key → content_piece is cross-domain; → locale is intra-domain.
2810
+ translation_key_localises_content_piece: { forward_verb: "localises", reverse_verb: "localised_by", classification: "cross-domain", source_type: "translation_key", target_type: "content_piece" },
2811
+ translation_key_targets_locale: { forward_verb: "targets", reverse_verb: "targeted_by", classification: "semantic", source_type: "translation_key", target_type: "locale" },
2812
+ // partner_revenue_share → revenue_stream (ecosystem → business_model). The
2813
+ // share governed a partner tier but never fed the revenue stream it
2814
+ // contributes to — partner economics could not roll up to the model.
2815
+ 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" },
2816
+ // retrospective (team_org) had 0 outbound — its outputs (learnings, decisions/
2817
+ // action items) could not leave the ceremony. A retrospective PRODUCES a
2818
+ // learning and YIELDS a decision. Both targets cross-domain.
2819
+ retrospective_produces_learning: { forward_verb: "produces", reverse_verb: "produced_in", classification: "cross-domain", source_type: "retrospective", target_type: "learning" },
2820
+ retrospective_yields_decision: { forward_verb: "yields", reverse_verb: "decided_in", classification: "cross-domain", source_type: "retrospective", target_type: "decision" },
2821
+ // status_report → milestone (program_mgmt). A report had 0 outbound; it could
2822
+ // not name the milestone whose status it reports. Intra-domain → semantic.
2823
+ status_report_reports_on_milestone: { forward_verb: "reports_on", reverse_verb: "reported_in", classification: "semantic", source_type: "status_report", target_type: "milestone" },
2824
+ // quote_document → deal (sales). A quote had 0 outbound; it could not advance
2825
+ // the deal it prices. Intra-domain and directional → causal.
2826
+ quote_document_advances_deal: { forward_verb: "advances", reverse_verb: "advanced_by", classification: "causal", source_type: "quote_document", target_type: "deal" },
2827
+ // data_quality_rule → data_source (data_analytics). A quality rule had 0
2828
+ // outbound; it could not name the source it governs. Intra-domain → semantic.
2829
+ data_quality_rule_governs_data_source: { forward_verb: "governs", reverse_verb: "governed_by", classification: "semantic", source_type: "data_quality_rule", target_type: "data_source" },
2830
+ // press_release → launch (marketing → go_to_market). A press release had 0
2831
+ // outbound; it could not name the launch it announces.
2832
+ press_release_announces_launch: { forward_verb: "announces", reverse_verb: "announced_by", classification: "cross-domain", source_type: "press_release", target_type: "launch" }
2717
2833
  };
2718
2834
  var UPG_POLYMORPHIC_EDGE_KEYS = [
2719
2835
  // Universal semantic verbs
@@ -3062,7 +3178,11 @@ var UPG_VALID_CHILDREN = {
3062
3178
  "survey_response"
3063
3179
  ],
3064
3180
  observation: ["quote"],
3065
- affinity_cluster: ["insight"],
3181
+ // F6 (UPG-672): affinity_cluster owns the observations it groups, in addition
3182
+ // to the insights it synthesises. Pairs with `affinity_cluster_groups_observation`
3183
+ // in the edge catalog (hierarchy). An observation can be both directly owned by
3184
+ // its research_study and grouped under an affinity_cluster (multi-parent grammar).
3185
+ affinity_cluster: ["insight", "observation"],
3066
3186
  // insight refines into insight; a raw insight can be distilled
3067
3187
  // into a more specific insight (refines_into chain).
3068
3188
  // v0.5.8 (UPG-528 Part 2d): insights own their evidencing quotes;
@@ -10280,6 +10400,7 @@ var UPG_PROPERTY_SCHEMA = {
10280
10400
  },
10281
10401
  // LearningPathProperties: Learning path.
10282
10402
  learning_path: {
10403
+ 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." },
10283
10404
  path_difficulty: { type: "string", enum: ["beginner", "intermediate", "advanced"], description: "Overall difficulty level of the learning path" },
10284
10405
  item_count: { type: "number", description: "Number of items (tutorials, videos, etc.) in the path" },
10285
10406
  estimated_hours: { type: "number", description: "Estimated total hours to complete the path" },
@@ -10429,6 +10550,7 @@ var UPG_PROPERTY_SCHEMA = {
10429
10550
  },
10430
10551
  // MilestoneProperties: Milestone.
10431
10552
  milestone: {
10553
+ 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`." },
10432
10554
  due_date: { type: "string", description: "Target due date (ISO format)" },
10433
10555
  met_on_time: { type: "boolean", description: "Whether the milestone was met on time" }
10434
10556
  },
@@ -10633,6 +10755,7 @@ var UPG_PROPERTY_SCHEMA = {
10633
10755
  },
10634
10756
  // PartnerTierProperties: Partner tier.
10635
10757
  partner_tier: {
10758
+ 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." },
10636
10759
  tier_level: { type: "number", description: "Numeric rank of the tier (higher = more prestigious)" },
10637
10760
  requirements: { type: "string[]", description: "What a partner must achieve to reach this tier" },
10638
10761
  benefits: { type: "string[]", description: "Benefits granted at this tier level" }
@@ -11055,6 +11178,7 @@ var UPG_PROPERTY_SCHEMA = {
11055
11178
  },
11056
11179
  // ScreenStateProperties: Specific state of a screen.
11057
11180
  screen_state: {
11181
+ 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)." },
11058
11182
  state_name: { type: "string", enum: ["empty", "loading", "error", "populated", "skeleton", "partial"], description: "State" },
11059
11183
  trigger: { type: "string", description: "Cause for entering this state" },
11060
11184
  condition: { type: "string", description: "Data or environmental condition the state represents" },
@@ -11567,6 +11691,7 @@ var UPG_PROPERTY_SCHEMA = {
11567
11691
  },
11568
11692
  // UserFlowProperties: User flow.
11569
11693
  user_flow: {
11694
+ 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." },
11570
11695
  trigger: { type: "string", description: "Initiating event" },
11571
11696
  steps: { type: "string[]", description: "Ordered steps" },
11572
11697
  success_state: { type: "string", description: "Successful completion" },
@@ -17630,7 +17755,10 @@ var PRIORITY_LABELS = [
17630
17755
  {
17631
17756
  id: "solution",
17632
17757
  canonical_label: "Solution",
17633
- alt_labels: ["proposed solution", "solution idea", "concept", "approach"],
17758
+ // 'concept' stripped (P-B / UPG-670): bare "concept" was shared with the
17759
+ // distinct `design_concept` type. `design_concept` keeps it; here a search
17760
+ // for a solution uses "approach" / "proposed solution".
17761
+ alt_labels: ["proposed solution", "solution idea", "approach"],
17634
17762
  framework_labels: {
17635
17763
  ost: "Solution",
17636
17764
  design_thinking: "Solution",
@@ -17793,7 +17921,10 @@ var PRIORITY_LABELS = [
17793
17921
  {
17794
17922
  id: "outcome",
17795
17923
  canonical_label: "Outcome",
17796
- alt_labels: ["desired outcome", "product outcome", "business outcome", "target outcome"],
17924
+ // 'desired outcome' stripped (P-B / UPG-670): it was the canonical label of
17925
+ // the distinct `desired_outcome` (Ulwick JTBD) type. The OST framework_label
17926
+ // below still surfaces "Desired Outcome" in OST context, framework-scoped.
17927
+ alt_labels: ["product outcome", "business outcome", "target outcome"],
17797
17928
  framework_labels: {
17798
17929
  ost: "Desired Outcome",
17799
17930
  okr_tree: "Outcome"
@@ -17821,7 +17952,10 @@ var PRIORITY_LABELS = [
17821
17952
  {
17822
17953
  id: "feature",
17823
17954
  canonical_label: "Feature",
17824
- alt_labels: ["capability", "product feature", "functionality"],
17955
+ // 'capability' stripped (P-B / UPG-670): it is the canonical label of the
17956
+ // distinct `capability` type (Wardley / DDD). A search for "capability" must
17957
+ // resolve there, not to a feature.
17958
+ alt_labels: ["product feature", "functionality"],
17825
17959
  framework_labels: {
17826
17960
  rice: "Scored Item",
17827
17961
  moscow: "Prioritised Item",
@@ -17892,7 +18026,10 @@ var PRIORITY_LABELS = [
17892
18026
  {
17893
18027
  id: "distribution_channel",
17894
18028
  canonical_label: "Distribution Channel",
17895
- alt_labels: ["channel", "sales channel", "delivery channel", "distribution"],
18029
+ // bare 'channel' stripped (P-B / UPG-670): shared 3-way with
18030
+ // `acquisition_channel` and `marketing_channel`. BMC/Lean-Canvas framework
18031
+ // contexts still surface "Channel" via framework_labels below.
18032
+ alt_labels: ["distribution channel", "sales channel", "delivery channel", "distribution"],
17896
18033
  framework_labels: {
17897
18034
  bmc: "Channel",
17898
18035
  lean_canvas: "Channel"
@@ -18072,7 +18209,8 @@ var PRIORITY_LABELS = [
18072
18209
  ];
18073
18210
  var STANDARD_LABELS = {
18074
18211
  // Strategic layer
18075
- product: { alt_labels: ["offering", "app", "service", "platform"] },
18212
+ // 'service' stripped (P-B / UPG-670): canonical label of the distinct `service` type.
18213
+ product: { alt_labels: ["offering", "app", "platform"] },
18076
18214
  vision: { alt_labels: ["product vision", "north star vision", "long-term vision"] },
18077
18215
  mission: { alt_labels: ["mission statement", "purpose"] },
18078
18216
  strategic_theme: { alt_labels: ["focus area", "strategic focus area"] },
@@ -18090,7 +18228,8 @@ var STANDARD_LABELS = {
18090
18228
  design_sprint: { alt_labels: ["sprint", "gv sprint", "google ventures sprint"] },
18091
18229
  // Validation layer
18092
18230
  learning: { alt_labels: ["validated learning", "lesson learned", "takeaway"] },
18093
- test_plan: { alt_labels: ["experiment plan", "validation plan"] },
18231
+ // 'experiment plan' stripped (P-B / UPG-670): canonical label of the distinct `experiment_plan` type.
18232
+ test_plan: { alt_labels: ["test strategy", "validation plan"] },
18094
18233
  research_plan: { alt_labels: ["study plan", "research brief"] },
18095
18234
  evidence: { alt_labels: ["proof", "supporting data", "signal"] },
18096
18235
  variant: { alt_labels: ["test variant", "experiment arm", "variation"] },
@@ -18098,7 +18237,9 @@ var STANDARD_LABELS = {
18098
18237
  competitor: { alt_labels: ["rival", "alternative", "competitive product", "competing product"] },
18099
18238
  competitor_feature: { alt_labels: ["competitive feature", "rival capability"] },
18100
18239
  market_trend: { alt_labels: ["trend", "industry trend", "macro trend"] },
18101
- market_segment: { alt_labels: ["segment", "market slice", "tam segment", "sam segment"] },
18240
+ // bare 'segment' stripped (P-B / UPG-670): shared 2-way with `behavioral_segment`.
18241
+ // 'market segment' is the qualified, unambiguous form.
18242
+ market_segment: { alt_labels: ["market segment", "market slice", "tam segment", "sam segment"] },
18102
18243
  competitive_analysis: { alt_labels: ["competitor analysis", "competitive landscape", "market analysis"] },
18103
18244
  // UX Research layer
18104
18245
  research_study: { alt_labels: ["study", "user study", "research project", "ux study"] },
@@ -18134,7 +18275,8 @@ var STANDARD_LABELS = {
18134
18275
  brand_typography: { alt_labels: ["typeface", "font family", "type system"] },
18135
18276
  brand_voice: { alt_labels: ["tone of voice", "brand tone", "writing style"] },
18136
18277
  // Product Specification layer
18137
- epic: { alt_labels: ["initiative", "large story", "feature set"] },
18278
+ // 'initiative' stripped (P-B / UPG-670): canonical label of the distinct `initiative` type.
18279
+ epic: { alt_labels: ["large story", "feature set"] },
18138
18280
  feature_area: { alt_labels: ["feature group", "capability area", "module"] },
18139
18281
  acceptance_criterion: { alt_labels: ["ac", "done criterion", "acceptance criteria", "definition of done"] },
18140
18282
  release: { alt_labels: ["version", "ship", "launch version", "build"] },
@@ -18148,8 +18290,10 @@ var STANDARD_LABELS = {
18148
18290
  // Engineering layer
18149
18291
  bounded_context: { alt_labels: ["context", "domain boundary", "module boundary"] },
18150
18292
  service: { alt_labels: ["microservice", "backend service", "api service"] },
18151
- domain_event: { alt_labels: ["event", "system event", "business event"] },
18152
- api_contract: { alt_labels: ["api spec", "api schema", "contract", "openapi spec"] },
18293
+ // 'event' stripped (P-B / UPG-670): canonical label of the distinct `event` type.
18294
+ domain_event: { alt_labels: ["system event", "business event"] },
18295
+ // 'contract' stripped (P-B / UPG-670): canonical label of the distinct `contract` (legal) type.
18296
+ api_contract: { alt_labels: ["api spec", "api schema", "openapi spec"] },
18153
18297
  technical_debt_item: { alt_labels: ["tech debt", "debt", "tech debt item", "cleanup"] },
18154
18298
  feature_flag: { alt_labels: ["flag", "toggle", "feature toggle", "release flag"] },
18155
18299
  aggregate: { alt_labels: ["aggregate root", "ddd aggregate"] },
@@ -18162,15 +18306,19 @@ var STANDARD_LABELS = {
18162
18306
  queue_topic: { alt_labels: ["topic", "message queue", "event bus topic", "pubsub topic"] },
18163
18307
  build_artifact: { alt_labels: ["artifact", "binary", "docker image", "package"] },
18164
18308
  code_repository: { alt_labels: ["repo", "repository", "git repo", "codebase"] },
18165
- library_dependency: { alt_labels: ["dependency", "package", "library", "npm package"] },
18309
+ // 'dependency' stripped (P-B / UPG-670): canonical label of the distinct `dependency` type.
18310
+ library_dependency: { alt_labels: ["package", "library", "npm package"] },
18166
18311
  integration_pattern: { alt_labels: ["integration", "pattern", "middleware pattern"] },
18167
18312
  external_api: { alt_labels: ["third-party api", "vendor api", "saas integration"] },
18168
18313
  data_flow: { alt_labels: ["data movement", "data transfer", "pipeline flow"] },
18169
18314
  // Growth layer
18170
- acquisition_channel: { alt_labels: ["channel", "traffic source", "user source"] },
18315
+ // bare 'channel' stripped (P-B / UPG-670): shared 3-way (see distribution_channel).
18316
+ acquisition_channel: { alt_labels: ["acquisition channel", "traffic source", "user source"] },
18171
18317
  growth_campaign: { alt_labels: ["campaign", "marketing campaign", "ad campaign", "growth campaign"] },
18172
18318
  cohort: { alt_labels: ["user cohort", "retention cohort", "signup cohort"] },
18173
- behavioral_segment: { alt_labels: ["segment", "user segment", "audience segment", "behavioural segment"] },
18319
+ // bare 'segment' stripped (P-B / UPG-670): shared 2-way with `market_segment`.
18320
+ // 'behavioral segment' / 'user segment' keep the affordance unambiguously.
18321
+ behavioral_segment: { alt_labels: ["user segment", "audience segment", "behavioural segment"] },
18174
18322
  growth_loop: { alt_labels: ["viral loop", "referral loop", "flywheel"] },
18175
18323
  attribution_model: { alt_labels: ["attribution", "marketing attribution", "channel attribution"] },
18176
18324
  // Business Model layer
@@ -18199,7 +18347,8 @@ var STANDARD_LABELS = {
18199
18347
  retrospective: { alt_labels: ["retro", "sprint retro", "team retro", "post-mortem"] },
18200
18348
  dependency: { alt_labels: ["team dependency", "cross-team dependency", "blocker"] },
18201
18349
  department: { alt_labels: ["org unit", "division", "business unit"] },
18202
- skill: { alt_labels: ["competency", "capability", "expertise"] },
18350
+ // 'capability' stripped (P-B / UPG-670): canonical label of the distinct `capability` type.
18351
+ skill: { alt_labels: ["competency", "expertise"] },
18203
18352
  ceremony: { alt_labels: ["ritual", "meeting cadence", "standup", "retrospective meeting"] },
18204
18353
  capacity_plan: { alt_labels: ["resourcing plan", "staffing plan", "headcount plan"] },
18205
18354
  // Data & Analytics layer
@@ -18209,7 +18358,8 @@ var STANDARD_LABELS = {
18209
18358
  data_model: { alt_labels: ["erd", "entity relationship diagram", "schema model"] },
18210
18359
  data_quality_rule: { alt_labels: ["data rule", "quality check", "data validation"] },
18211
18360
  data_product: { alt_labels: ["data asset", "data offering"] },
18212
- data_pipeline: { alt_labels: ["etl", "elt", "ingestion pipeline", "data flow"] },
18361
+ // 'data flow' stripped (P-B / UPG-670): canonical label of the distinct `data_flow` type.
18362
+ data_pipeline: { alt_labels: ["etl", "elt", "ingestion pipeline"] },
18213
18363
  data_lineage: { alt_labels: ["lineage", "data provenance", "data trail"] },
18214
18364
  glossary_term: { alt_labels: ["term", "definition", "business term"] },
18215
18365
  data_domain: { alt_labels: ["data area", "data subject area"] },
@@ -18251,7 +18401,8 @@ var STANDARD_LABELS = {
18251
18401
  error_budget: { alt_labels: ["reliability budget", "downtime budget"] },
18252
18402
  investigation: { alt_labels: ["incident investigation", "root cause analysis", "debugging"] },
18253
18403
  postmortem: { alt_labels: ["post-mortem", "incident review", "rca", "root cause analysis"] },
18254
- runbook: { alt_labels: ["operations guide", "playbook", "sop", "standard operating procedure"] },
18404
+ // 'playbook' stripped (P-B / UPG-670): canonical label of the distinct `playbook` type.
18405
+ runbook: { alt_labels: ["operations guide", "sop", "standard operating procedure"] },
18255
18406
  monitor: { alt_labels: ["health check", "synthetic monitor", "uptime check"] },
18256
18407
  alert_rule: { alt_labels: ["alert", "pager rule", "notification rule"] },
18257
18408
  release_strategy: { alt_labels: ["rollout strategy", "deployment strategy", "canary release"] },
@@ -18266,17 +18417,26 @@ var STANDARD_LABELS = {
18266
18417
  security_control: { alt_labels: ["control", "safeguard", "countermeasure", "mitigation"] },
18267
18418
  security_policy: { alt_labels: ["infosec policy", "security standard"] },
18268
18419
  penetration_test: { alt_labels: ["pentest", "pen test", "security test"] },
18269
- security_review: { alt_labels: ["code review", "security assessment", "audit"] },
18420
+ // bare 'audit' / 'security assessment' stripped (P-B / UPG-670): both owned by
18421
+ // `security_audit`. A `security_review` is a code-review-scoped activity; the
18422
+ // qualified 'security code review' keeps it findable without colliding.
18423
+ security_review: { alt_labels: ["code review", "security code review"] },
18270
18424
  data_classification: { alt_labels: ["classification", "sensitivity level", "data label"] },
18271
18425
  access_policy: { alt_labels: ["iam policy", "rbac rule", "permission", "access control"] },
18272
18426
  // Sales & Revenue layer
18273
- account: { alt_labels: ["customer account", "client", "organization"] },
18274
- contact: { alt_labels: ["person", "buyer", "champion"] },
18427
+ // 'organization' stripped (P-B / UPG-670): canonical label of the distinct `organization` type.
18428
+ account: { alt_labels: ["customer account", "client"] },
18429
+ // 'person' stripped (P-B / UPG-670): canonical label of the distinct `person` type.
18430
+ contact: { alt_labels: ["buyer", "champion"] },
18275
18431
  lead: { alt_labels: ["prospect", "mql", "sql", "marketing lead"] },
18276
- deal: { alt_labels: ["opportunity", "sales opportunity", "opp"] },
18432
+ // 'opportunity' stripped (P-B / UPG-670): canonical label of the distinct `opportunity` (OST) type.
18433
+ deal: { alt_labels: ["sales opportunity", "opp"] },
18277
18434
  pipeline_sales: { alt_labels: ["sales pipeline", "deal pipeline", "revenue pipeline"] },
18278
18435
  pipeline_stage: { alt_labels: ["deal stage", "sales stage"] },
18279
- quote_document: { alt_labels: ["quote", "proposal", "estimate", "quotation"] },
18436
+ // bare 'quote' qualified to 'sales quote' (P-B / UPG-670): 'quote' is the
18437
+ // canonical label of the distinct `quote` type. The qualified form keeps the
18438
+ // sales-document search affordance without misresolving.
18439
+ quote_document: { alt_labels: ["sales quote", "proposal", "estimate", "quotation"] },
18280
18440
  subscription: { alt_labels: ["recurring revenue", "saas subscription", "plan"] },
18281
18441
  invoice: { alt_labels: ["bill", "payment request"] },
18282
18442
  forecast: { alt_labels: ["revenue forecast", "sales forecast", "projection"] },
@@ -18297,7 +18457,8 @@ var STANDARD_LABELS = {
18297
18457
  a11y_annotation: { alt_labels: ["accessibility annotation", "aria note"] },
18298
18458
  // Marketing & Communications layer
18299
18459
  marketing_strategy: { alt_labels: ["marketing plan", "growth strategy"] },
18300
- marketing_channel: { alt_labels: ["channel", "paid channel", "organic channel"] },
18460
+ // bare 'channel' stripped (P-B / UPG-670): shared 3-way (see distribution_channel).
18461
+ marketing_channel: { alt_labels: ["marketing channel", "paid channel", "organic channel"] },
18301
18462
  marketing_campaign_plan: { alt_labels: ["campaign plan", "launch campaign"] },
18302
18463
  email_sequence: { alt_labels: ["drip campaign", "nurture sequence", "email flow"] },
18303
18464
  social_post: { alt_labels: ["tweet", "linkedin post", "social media post"] },
@@ -18371,7 +18532,9 @@ var STANDARD_LABELS = {
18371
18532
  agent_session: { alt_labels: ["session", "agent run", "agent conversation"] },
18372
18533
  review_gate: { alt_labels: ["approval gate", "quality gate", "stage gate"] },
18373
18534
  approval_record: { alt_labels: ["approval", "sign-off", "authorization"] },
18374
- agent_skill: { alt_labels: ["skill", "tool", "agent capability"] },
18535
+ // bare 'skill' qualified to 'agent skill' (P-B / UPG-670): 'skill' is the
18536
+ // canonical label of the distinct team_org `skill` type.
18537
+ agent_skill: { alt_labels: ["agent skill", "tool", "agent capability"] },
18375
18538
  agent_hook: { alt_labels: ["hook", "trigger", "callback"] },
18376
18539
  workflow_artifact: { alt_labels: ["artifact", "output artifact", "generated artifact"] },
18377
18540
  // Portfolio layer
@@ -23515,6 +23678,96 @@ var UPG_ANTI_PATTERNS = [
23515
23678
  stages: ["concept", "validation", "build", "beta", "launch", "growth"],
23516
23679
  severity: "high",
23517
23680
  source: { kind: "fundamental" }
23681
+ },
23682
+ // ── F5 (UPG-671): anti-pattern enforcement ────────────────────────────────
23683
+ // P-C from the 36-domain wiring audit: domain-guide anti-patterns described
23684
+ // in prose with no machine-checkable detector. These two map cleanly to a
23685
+ // RelationshipCheck (edge presence/absence) and are promoted here.
23686
+ {
23687
+ id: "insights-without-evidence",
23688
+ name: "Insights without evidence",
23689
+ 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.",
23690
+ structured_condition: {
23691
+ operator: "and",
23692
+ checks: [
23693
+ { check: { type: "entity_count", entity_type: "insight", comparison: "nonzero" } },
23694
+ {
23695
+ check: {
23696
+ type: "relationship",
23697
+ source_type: "observation",
23698
+ edge_type: "observation_yields_insight",
23699
+ target_type: "insight",
23700
+ comparison: "not_exists"
23701
+ }
23702
+ },
23703
+ {
23704
+ check: {
23705
+ type: "relationship",
23706
+ source_type: "survey_response",
23707
+ edge_type: "survey_response_evidences_insight",
23708
+ target_type: "insight",
23709
+ comparison: "not_exists"
23710
+ }
23711
+ },
23712
+ {
23713
+ check: {
23714
+ type: "relationship",
23715
+ source_type: "insight",
23716
+ edge_type: "insight_evidenced_by_quote",
23717
+ target_type: "quote",
23718
+ comparison: "not_exists"
23719
+ }
23720
+ }
23721
+ ]
23722
+ },
23723
+ why_it_matters: "Insights untethered from evidence cannot be trusted, contested, or traced. Downstream opportunities and design questions inherit an unfalsifiable claim.",
23724
+ 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.",
23725
+ stages: ["concept", "validation", "build", "beta", "launch", "growth", "mature"],
23726
+ severity: "high",
23727
+ source: { kind: "practitioner", attribution: "Steve Portigal, Interviewing Users" }
23728
+ },
23729
+ {
23730
+ id: "feature-requests-without-provenance",
23731
+ name: "Feature requests without provenance",
23732
+ 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.",
23733
+ structured_condition: {
23734
+ operator: "and",
23735
+ checks: [
23736
+ { check: { type: "entity_count", entity_type: "feature_request", comparison: "nonzero" } },
23737
+ {
23738
+ check: {
23739
+ type: "relationship",
23740
+ source_type: "feedback_program",
23741
+ edge_type: "feedback_program_collects_feature_request",
23742
+ target_type: "feature_request",
23743
+ comparison: "not_exists"
23744
+ }
23745
+ },
23746
+ {
23747
+ check: {
23748
+ type: "relationship",
23749
+ source_type: "customer_feedback",
23750
+ edge_type: "customer_feedback_becomes_feature_request",
23751
+ target_type: "feature_request",
23752
+ comparison: "not_exists"
23753
+ }
23754
+ },
23755
+ {
23756
+ check: {
23757
+ type: "relationship",
23758
+ source_type: "feature_request",
23759
+ edge_type: "feature_request_from_behavioral_segment",
23760
+ target_type: "behavioral_segment",
23761
+ comparison: "not_exists"
23762
+ }
23763
+ }
23764
+ ]
23765
+ },
23766
+ 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.",
23767
+ 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.",
23768
+ stages: ["beta", "launch", "growth", "mature"],
23769
+ severity: "medium",
23770
+ source: { kind: "practitioner", attribution: "Marty Cagan, Inspired (product discovery)" }
23518
23771
  }
23519
23772
  ];
23520
23773
  function getAntiPatternById(id) {
@@ -23853,6 +24106,10 @@ var UPG_REGIONS = [
23853
24106
  "strategy"
23854
24107
  ],
23855
24108
  entities: [
24109
+ {
24110
+ type: "product",
24111
+ role: "container"
24112
+ },
23856
24113
  {
23857
24114
  type: "vision",
23858
24115
  role: "root"
@@ -23892,7 +24149,11 @@ var UPG_REGIONS = [
23892
24149
  {
23893
24150
  type: "metric",
23894
24151
  role: "leaf",
23895
- notes: "shared with Analytics"
24152
+ notes: "also anchors Analytics; canonical home is Strategy"
24153
+ },
24154
+ {
24155
+ type: "metric_quality_assessment",
24156
+ role: "leaf"
23896
24157
  },
23897
24158
  {
23898
24159
  type: "decision",
@@ -23903,6 +24164,10 @@ var UPG_REGIONS = [
23903
24164
  type: "assumption",
23904
24165
  role: "leaf"
23905
24166
  },
24167
+ {
24168
+ type: "constraint",
24169
+ role: "leaf"
24170
+ },
23906
24171
  {
23907
24172
  type: "outcome",
23908
24173
  role: "hub"
@@ -24016,7 +24281,7 @@ var UPG_REGIONS = [
24016
24281
  {
24017
24282
  type: "participant",
24018
24283
  role: "leaf",
24019
- notes: "research-resolved persona"
24284
+ notes: "research-resolved persona; canonical home is Discovery/Research/Validation"
24020
24285
  }
24021
24286
  ],
24022
24287
  anchor: {
@@ -24187,6 +24452,14 @@ var UPG_REGIONS = [
24187
24452
  role: "hub",
24188
24453
  notes: "self-nesting"
24189
24454
  },
24455
+ {
24456
+ type: "experiment_plan",
24457
+ role: "container"
24458
+ },
24459
+ {
24460
+ type: "experiment_run",
24461
+ role: "container"
24462
+ },
24190
24463
  {
24191
24464
  type: "learning",
24192
24465
  role: "leaf"
@@ -24356,10 +24629,6 @@ var UPG_REGIONS = [
24356
24629
  type: "competitive_analysis",
24357
24630
  role: "container"
24358
24631
  },
24359
- {
24360
- type: "territory",
24361
- role: "leaf"
24362
- },
24363
24632
  {
24364
24633
  type: "classification_axis",
24365
24634
  role: "container",
@@ -24379,7 +24648,7 @@ var UPG_REGIONS = [
24379
24648
  },
24380
24649
  intra_edges: [
24381
24650
  "competitor_offers_competitor_feature",
24382
- "competitive_analysis_contains_competitor",
24651
+ "competitive_analysis_analyses_competitor",
24383
24652
  "competitive_analysis_dimensioned_by_classification_axis",
24384
24653
  "classification_axis_includes_classification_value",
24385
24654
  "competitor_classified_as_classification_value"
@@ -24480,6 +24749,10 @@ var UPG_REGIONS = [
24480
24749
  type: "screen",
24481
24750
  role: "leaf"
24482
24751
  },
24752
+ {
24753
+ type: "screen_state",
24754
+ role: "leaf"
24755
+ },
24483
24756
  {
24484
24757
  type: "wireframe",
24485
24758
  role: "leaf"
@@ -24557,6 +24830,18 @@ var UPG_REGIONS = [
24557
24830
  type: "content_piece",
24558
24831
  role: "leaf"
24559
24832
  },
24833
+ {
24834
+ type: "knowledge_base_article",
24835
+ role: "leaf"
24836
+ },
24837
+ {
24838
+ type: "content_calendar",
24839
+ role: "container"
24840
+ },
24841
+ {
24842
+ type: "documentation_template",
24843
+ role: "leaf"
24844
+ },
24560
24845
  {
24561
24846
  type: "document",
24562
24847
  role: "leaf"
@@ -24575,13 +24860,13 @@ var UPG_REGIONS = [
24575
24860
  intra_edges: [
24576
24861
  "user_journey_contains_journey_step",
24577
24862
  "design_system_contains_design_component",
24578
- "brand_identity_contains_brand_colour",
24579
- "design_component_self_nests"
24863
+ "brand_identity_coloured_with_brand_colour",
24864
+ "design_component_composes_design_component"
24580
24865
  ],
24581
24866
  boundary_edges: [
24582
24867
  {
24583
24868
  direction: "import",
24584
- edge_id: "need_informs_design_question",
24869
+ edge_id: "need_reframed_as_design_question",
24585
24870
  crosses_into: "users_needs"
24586
24871
  },
24587
24872
  {
@@ -24605,8 +24890,8 @@ var UPG_REGIONS = [
24605
24890
  crosses_into: "engineering_platform"
24606
24891
  },
24607
24892
  {
24608
- direction: "sideways",
24609
- edge_id: "feature_sketched_in_wireframe",
24893
+ direction: "export",
24894
+ edge_id: "wireframe_specifies_feature",
24610
24895
  crosses_into: "product_delivery"
24611
24896
  },
24612
24897
  {
@@ -24681,20 +24966,68 @@ var UPG_REGIONS = [
24681
24966
  role: "container",
24682
24967
  notes: "semantic spanner, not containment"
24683
24968
  },
24969
+ {
24970
+ type: "changelog",
24971
+ role: "leaf"
24972
+ },
24973
+ {
24974
+ type: "feedback_program",
24975
+ role: "container"
24976
+ },
24977
+ {
24978
+ type: "feature_request",
24979
+ role: "leaf"
24980
+ },
24981
+ {
24982
+ type: "feedback_vote",
24983
+ role: "leaf"
24984
+ },
24985
+ {
24986
+ type: "nps_campaign",
24987
+ role: "leaf"
24988
+ },
24989
+ {
24990
+ type: "user_advisory_board",
24991
+ role: "container"
24992
+ },
24993
+ {
24994
+ type: "beta_program",
24995
+ role: "leaf"
24996
+ },
24997
+ {
24998
+ type: "feedback_theme",
24999
+ role: "leaf"
25000
+ },
25001
+ {
25002
+ type: "program",
25003
+ role: "container"
25004
+ },
25005
+ {
25006
+ type: "project",
25007
+ role: "container"
25008
+ },
24684
25009
  {
24685
25010
  type: "milestone",
25011
+ role: "leaf"
25012
+ },
25013
+ {
25014
+ type: "risk_register",
24686
25015
  role: "container"
24687
25016
  },
24688
25017
  {
24689
- type: "changelog",
25018
+ type: "change_request",
24690
25019
  role: "leaf"
24691
25020
  },
24692
25021
  {
24693
- type: "feature_request",
25022
+ type: "deliverable",
24694
25023
  role: "leaf"
24695
25024
  },
24696
25025
  {
24697
- type: "feedback_vote",
25026
+ type: "resource_allocation",
25027
+ role: "leaf"
25028
+ },
25029
+ {
25030
+ type: "status_report",
24698
25031
  role: "leaf"
24699
25032
  }
24700
25033
  ],
@@ -24763,8 +25096,8 @@ var UPG_REGIONS = [
24763
25096
  crosses_into: "discovery_research_validation"
24764
25097
  },
24765
25098
  {
24766
- direction: "sideways",
24767
- edge_id: "feature_sketched_in_wireframe",
25099
+ direction: "import",
25100
+ edge_id: "wireframe_specifies_feature",
24768
25101
  crosses_into: "experience_design_brand"
24769
25102
  },
24770
25103
  {
@@ -24827,10 +25160,6 @@ var UPG_REGIONS = [
24827
25160
  type: "database_schema",
24828
25161
  role: "leaf"
24829
25162
  },
24830
- {
24831
- type: "data_model",
24832
- role: "leaf"
24833
- },
24834
25163
  {
24835
25164
  type: "aggregate",
24836
25165
  role: "container"
@@ -24895,6 +25224,111 @@ var UPG_REGIONS = [
24895
25224
  {
24896
25225
  type: "technical_debt_item",
24897
25226
  role: "leaf"
25227
+ },
25228
+ {
25229
+ type: "investigation",
25230
+ role: "container"
25231
+ },
25232
+ {
25233
+ type: "root_cause",
25234
+ role: "container"
25235
+ },
25236
+ {
25237
+ type: "symptom",
25238
+ role: "leaf"
25239
+ },
25240
+ {
25241
+ type: "fix",
25242
+ role: "leaf"
25243
+ },
25244
+ {
25245
+ type: "ai_model",
25246
+ role: "container"
25247
+ },
25248
+ {
25249
+ type: "prompt_template",
25250
+ role: "leaf"
25251
+ },
25252
+ {
25253
+ type: "prompt_version",
25254
+ role: "leaf"
25255
+ },
25256
+ {
25257
+ type: "eval_benchmark",
25258
+ role: "container"
25259
+ },
25260
+ {
25261
+ type: "eval_run",
25262
+ role: "leaf"
25263
+ },
25264
+ {
25265
+ type: "ai_cost_tracker",
25266
+ role: "leaf"
25267
+ },
25268
+ {
25269
+ type: "hallucination_report",
25270
+ role: "leaf"
25271
+ },
25272
+ {
25273
+ type: "ai_guardrail",
25274
+ role: "leaf"
25275
+ },
25276
+ {
25277
+ type: "model_comparison",
25278
+ role: "leaf"
25279
+ },
25280
+ {
25281
+ type: "ai_experiment",
25282
+ role: "leaf"
25283
+ },
25284
+ {
25285
+ type: "ai_dataset",
25286
+ role: "leaf"
25287
+ },
25288
+ {
25289
+ type: "ai_trace",
25290
+ role: "container",
25291
+ notes: "self-nesting inference chain"
25292
+ },
25293
+ {
25294
+ type: "workflow_template",
25295
+ role: "container"
25296
+ },
25297
+ {
25298
+ type: "workflow_run",
25299
+ role: "container"
25300
+ },
25301
+ {
25302
+ type: "workflow_artifact",
25303
+ role: "leaf"
25304
+ },
25305
+ {
25306
+ type: "agent_definition",
25307
+ role: "container"
25308
+ },
25309
+ {
25310
+ type: "agent_session",
25311
+ role: "leaf"
25312
+ },
25313
+ {
25314
+ type: "agent_skill",
25315
+ role: "leaf"
25316
+ },
25317
+ {
25318
+ type: "agent_hook",
25319
+ role: "leaf"
25320
+ },
25321
+ {
25322
+ type: "agent_task",
25323
+ role: "leaf"
25324
+ },
25325
+ {
25326
+ type: "review_gate",
25327
+ role: "container"
25328
+ },
25329
+ {
25330
+ type: "approval_record",
25331
+ role: "leaf"
24898
25332
  }
24899
25333
  ],
24900
25334
  anchor: {
@@ -24913,7 +25347,7 @@ var UPG_REGIONS = [
24913
25347
  "service_depends_on_library_dependency",
24914
25348
  "service_carries_technical_debt_item",
24915
25349
  "service_toggles_feature_flag",
24916
- "service_caused_by_root_cause",
25350
+ "service_affected_by_root_cause",
24917
25351
  "service_investigated_via_investigation"
24918
25352
  ],
24919
25353
  boundary_edges: [
@@ -24997,6 +25431,26 @@ var UPG_REGIONS = [
24997
25431
  type: "unit_economics",
24998
25432
  role: "leaf"
24999
25433
  },
25434
+ {
25435
+ type: "partnership",
25436
+ role: "leaf"
25437
+ },
25438
+ {
25439
+ type: "key_resource",
25440
+ role: "leaf"
25441
+ },
25442
+ {
25443
+ type: "key_activity",
25444
+ role: "leaf"
25445
+ },
25446
+ {
25447
+ type: "customer_relationship",
25448
+ role: "leaf"
25449
+ },
25450
+ {
25451
+ type: "distribution_channel",
25452
+ role: "leaf"
25453
+ },
25000
25454
  {
25001
25455
  type: "pricing_strategy",
25002
25456
  role: "root"
@@ -25005,6 +25459,18 @@ var UPG_REGIONS = [
25005
25459
  type: "pricing_tier",
25006
25460
  role: "leaf"
25007
25461
  },
25462
+ {
25463
+ type: "discount_strategy",
25464
+ role: "leaf"
25465
+ },
25466
+ {
25467
+ type: "trial_config",
25468
+ role: "leaf"
25469
+ },
25470
+ {
25471
+ type: "paywall",
25472
+ role: "leaf"
25473
+ },
25008
25474
  {
25009
25475
  type: "gtm_strategy",
25010
25476
  role: "root"
@@ -25021,10 +25487,30 @@ var UPG_REGIONS = [
25021
25487
  type: "messaging",
25022
25488
  role: "leaf"
25023
25489
  },
25490
+ {
25491
+ type: "content_strategy",
25492
+ role: "container"
25493
+ },
25494
+ {
25495
+ type: "sales_motion",
25496
+ role: "leaf"
25497
+ },
25498
+ {
25499
+ type: "demand_gen_program",
25500
+ role: "leaf"
25501
+ },
25502
+ {
25503
+ type: "territory",
25504
+ role: "leaf"
25505
+ },
25024
25506
  {
25025
25507
  type: "objection",
25026
25508
  role: "leaf"
25027
25509
  },
25510
+ {
25511
+ type: "rebuttal",
25512
+ role: "container"
25513
+ },
25028
25514
  {
25029
25515
  type: "proof_point",
25030
25516
  role: "leaf"
@@ -25072,6 +25558,114 @@ var UPG_REGIONS = [
25072
25558
  {
25073
25559
  type: "variant",
25074
25560
  role: "leaf"
25561
+ },
25562
+ {
25563
+ type: "account",
25564
+ role: "container"
25565
+ },
25566
+ {
25567
+ type: "contact",
25568
+ role: "leaf"
25569
+ },
25570
+ {
25571
+ type: "lead",
25572
+ role: "leaf"
25573
+ },
25574
+ {
25575
+ type: "deal",
25576
+ role: "container"
25577
+ },
25578
+ {
25579
+ type: "pipeline_sales",
25580
+ role: "container"
25581
+ },
25582
+ {
25583
+ type: "pipeline_stage",
25584
+ role: "leaf"
25585
+ },
25586
+ {
25587
+ type: "quote_document",
25588
+ role: "leaf"
25589
+ },
25590
+ {
25591
+ type: "subscription",
25592
+ role: "container"
25593
+ },
25594
+ {
25595
+ type: "invoice",
25596
+ role: "leaf"
25597
+ },
25598
+ {
25599
+ type: "forecast",
25600
+ role: "leaf"
25601
+ },
25602
+ {
25603
+ type: "marketing_strategy",
25604
+ role: "container"
25605
+ },
25606
+ {
25607
+ type: "marketing_channel",
25608
+ role: "container"
25609
+ },
25610
+ {
25611
+ type: "marketing_campaign_plan",
25612
+ role: "container"
25613
+ },
25614
+ {
25615
+ type: "email_sequence",
25616
+ role: "leaf"
25617
+ },
25618
+ {
25619
+ type: "social_post",
25620
+ role: "leaf"
25621
+ },
25622
+ {
25623
+ type: "seo_keyword",
25624
+ role: "leaf"
25625
+ },
25626
+ {
25627
+ type: "ad_creative",
25628
+ role: "leaf"
25629
+ },
25630
+ {
25631
+ type: "press_release",
25632
+ role: "leaf"
25633
+ },
25634
+ {
25635
+ type: "event",
25636
+ role: "leaf"
25637
+ },
25638
+ {
25639
+ type: "community_initiative",
25640
+ role: "leaf"
25641
+ },
25642
+ {
25643
+ type: "partner_program",
25644
+ role: "container"
25645
+ },
25646
+ {
25647
+ type: "partner_tier",
25648
+ role: "leaf"
25649
+ },
25650
+ {
25651
+ type: "api_ecosystem",
25652
+ role: "container"
25653
+ },
25654
+ {
25655
+ type: "marketplace_listing",
25656
+ role: "leaf"
25657
+ },
25658
+ {
25659
+ type: "developer_portal",
25660
+ role: "leaf"
25661
+ },
25662
+ {
25663
+ type: "integration_partner",
25664
+ role: "leaf"
25665
+ },
25666
+ {
25667
+ type: "partner_revenue_share",
25668
+ role: "leaf"
25075
25669
  }
25076
25670
  ],
25077
25671
  anchor: {
@@ -25178,7 +25772,8 @@ var UPG_REGIONS = [
25178
25772
  entities: [
25179
25773
  {
25180
25774
  type: "metric",
25181
- role: "anchor"
25775
+ role: "anchor",
25776
+ notes: "canonical home is Strategy; anchors Analytics as the measurement plane"
25182
25777
  },
25183
25778
  {
25184
25779
  type: "data_source",
@@ -25192,24 +25787,36 @@ var UPG_REGIONS = [
25192
25787
  type: "dashboard",
25193
25788
  role: "container"
25194
25789
  },
25790
+ {
25791
+ type: "data_model",
25792
+ role: "leaf"
25793
+ },
25195
25794
  {
25196
25795
  type: "data_domain",
25197
25796
  role: "container"
25198
25797
  },
25199
25798
  {
25200
- type: "glossary_term",
25799
+ type: "data_product",
25201
25800
  role: "leaf"
25202
25801
  },
25203
25802
  {
25204
- type: "forecast",
25803
+ type: "data_pipeline",
25205
25804
  role: "leaf"
25206
25805
  },
25207
25806
  {
25208
- type: "data_quality_rule",
25807
+ type: "data_lineage",
25209
25808
  role: "leaf"
25210
25809
  },
25211
25810
  {
25212
- type: "data_contract",
25811
+ type: "glossary_term",
25812
+ role: "leaf"
25813
+ },
25814
+ {
25815
+ type: "report",
25816
+ role: "leaf"
25817
+ },
25818
+ {
25819
+ type: "data_quality_rule",
25213
25820
  role: "leaf"
25214
25821
  }
25215
25822
  ],
@@ -25335,7 +25942,27 @@ var UPG_REGIONS = [
25335
25942
  {
25336
25943
  type: "deployment",
25337
25944
  role: "leaf",
25338
- notes: "shared with Engineering"
25945
+ notes: "canonical home is Engineering; release event surfaced to Ops"
25946
+ },
25947
+ {
25948
+ type: "alert_rule",
25949
+ role: "leaf"
25950
+ },
25951
+ {
25952
+ type: "ci_pipeline",
25953
+ role: "container"
25954
+ },
25955
+ {
25956
+ type: "release_strategy",
25957
+ role: "leaf"
25958
+ },
25959
+ {
25960
+ type: "on_call_rotation",
25961
+ role: "leaf"
25962
+ },
25963
+ {
25964
+ type: "infrastructure_component",
25965
+ role: "container"
25339
25966
  },
25340
25967
  {
25341
25968
  type: "test_suite",
@@ -25353,10 +25980,26 @@ var UPG_REGIONS = [
25353
25980
  type: "test_result",
25354
25981
  role: "leaf"
25355
25982
  },
25983
+ {
25984
+ type: "regression_test",
25985
+ role: "leaf"
25986
+ },
25987
+ {
25988
+ type: "test_coverage_report",
25989
+ role: "leaf"
25990
+ },
25991
+ {
25992
+ type: "test_environment",
25993
+ role: "leaf"
25994
+ },
25356
25995
  {
25357
25996
  type: "threat_model",
25358
25997
  role: "root"
25359
25998
  },
25999
+ {
26000
+ type: "threat",
26001
+ role: "leaf"
26002
+ },
25360
26003
  {
25361
26004
  type: "security_control",
25362
26005
  role: "leaf"
@@ -25373,14 +26016,34 @@ var UPG_REGIONS = [
25373
26016
  type: "penetration_test",
25374
26017
  role: "leaf"
25375
26018
  },
26019
+ {
26020
+ type: "security_review",
26021
+ role: "container"
26022
+ },
26023
+ {
26024
+ type: "data_classification",
26025
+ role: "leaf"
26026
+ },
26027
+ {
26028
+ type: "access_policy",
26029
+ role: "leaf"
26030
+ },
25376
26031
  {
25377
26032
  type: "a11y_standard",
25378
26033
  role: "leaf"
25379
26034
  },
26035
+ {
26036
+ type: "a11y_guideline",
26037
+ role: "leaf"
26038
+ },
25380
26039
  {
25381
26040
  type: "a11y_audit",
25382
26041
  role: "leaf"
25383
26042
  },
26043
+ {
26044
+ type: "a11y_issue",
26045
+ role: "leaf"
26046
+ },
25384
26047
  {
25385
26048
  type: "a11y_annotation",
25386
26049
  role: "leaf"
@@ -25398,11 +26061,15 @@ var UPG_REGIONS = [
25398
26061
  role: "leaf"
25399
26062
  },
25400
26063
  {
25401
- type: "root_cause",
26064
+ type: "data_contract",
25402
26065
  role: "leaf"
25403
26066
  },
25404
26067
  {
25405
- type: "investigation",
26068
+ type: "audit_log_policy",
26069
+ role: "leaf"
26070
+ },
26071
+ {
26072
+ type: "security_audit",
25406
26073
  role: "leaf"
25407
26074
  },
25408
26075
  {
@@ -25431,16 +26098,16 @@ var UPG_REGIONS = [
25431
26098
  role: "root"
25432
26099
  },
25433
26100
  {
25434
- type: "beta_program",
26101
+ type: "customer_journey_stage",
25435
26102
  role: "container"
25436
26103
  },
25437
26104
  {
25438
- type: "feedback_program",
25439
- role: "container"
26105
+ type: "touchpoint",
26106
+ role: "leaf"
25440
26107
  },
25441
26108
  {
25442
- type: "user_advisory_board",
25443
- role: "container"
26109
+ type: "success_milestone",
26110
+ role: "leaf"
25444
26111
  },
25445
26112
  {
25446
26113
  type: "team",
@@ -25454,6 +26121,10 @@ var UPG_REGIONS = [
25454
26121
  type: "role",
25455
26122
  role: "leaf"
25456
26123
  },
26124
+ {
26125
+ type: "person",
26126
+ role: "leaf"
26127
+ },
25457
26128
  {
25458
26129
  type: "stakeholder",
25459
26130
  role: "leaf",
@@ -25481,6 +26152,78 @@ var UPG_REGIONS = [
25481
26152
  },
25482
26153
  {
25483
26154
  type: "capacity_plan",
26155
+ role: "leaf"
26156
+ },
26157
+ {
26158
+ type: "legal_entity",
26159
+ role: "container"
26160
+ },
26161
+ {
26162
+ type: "ip_asset",
26163
+ role: "leaf"
26164
+ },
26165
+ {
26166
+ type: "contract",
26167
+ role: "container"
26168
+ },
26169
+ {
26170
+ type: "contract_clause",
26171
+ role: "leaf"
26172
+ },
26173
+ {
26174
+ type: "privacy_policy",
26175
+ role: "leaf"
26176
+ },
26177
+ {
26178
+ type: "locale",
26179
+ role: "container"
26180
+ },
26181
+ {
26182
+ type: "translation_key",
26183
+ role: "leaf"
26184
+ },
26185
+ {
26186
+ type: "translation_bundle",
26187
+ role: "container"
26188
+ },
26189
+ {
26190
+ type: "locale_config",
26191
+ role: "leaf"
26192
+ },
26193
+ {
26194
+ type: "cultural_adaptation",
26195
+ role: "leaf"
26196
+ },
26197
+ {
26198
+ type: "regional_pricing",
26199
+ role: "leaf"
26200
+ },
26201
+ {
26202
+ type: "education_program",
26203
+ role: "container"
26204
+ },
26205
+ {
26206
+ type: "tutorial",
26207
+ role: "leaf"
26208
+ },
26209
+ {
26210
+ type: "walkthrough",
26211
+ role: "leaf"
26212
+ },
26213
+ {
26214
+ type: "webinar",
26215
+ role: "leaf"
26216
+ },
26217
+ {
26218
+ type: "certification",
26219
+ role: "leaf"
26220
+ },
26221
+ {
26222
+ type: "help_video",
26223
+ role: "leaf"
26224
+ },
26225
+ {
26226
+ type: "learning_path",
25484
26227
  role: "container"
25485
26228
  }
25486
26229
  ],
@@ -25497,7 +26240,6 @@ var UPG_REGIONS = [
25497
26240
  "incident_analysed_in_postmortem",
25498
26241
  "incident_triggers_postmortem",
25499
26242
  "incident_breaches_service_level_objective",
25500
- "incident_caused_by_root_cause",
25501
26243
  "incident_exploits_vulnerability"
25502
26244
  ],
25503
26245
  boundary_edges: [
@@ -25518,8 +26260,8 @@ var UPG_REGIONS = [
25518
26260
  },
25519
26261
  {
25520
26262
  direction: "export",
25521
- edge_id: "beta_program_runs_experiment",
25522
- crosses_into: "discovery_research_validation"
26263
+ edge_id: "incident_caused_by_root_cause",
26264
+ crosses_into: "engineering_platform"
25523
26265
  },
25524
26266
  {
25525
26267
  direction: "export",
@@ -26053,7 +26795,7 @@ function isCanonical(text) {
26053
26795
  }
26054
26796
 
26055
26797
  // src/index.ts
26056
- var UPG_VERSION = "0.9.6";
26798
+ var UPG_VERSION = "0.9.7";
26057
26799
  var UPG_FORMAT_VERSION = "0.4.0";
26058
26800
  var MARKDOWN_FORMAT_VERSION = "0.1";
26059
26801
  var UPG_TYPES = getTypes();