---
name: JIRA Decision Trees
version: 1.0.0
role: Structured decision flows for JIRA operations
description: Provides reusable decision trees that guide users through complex JIRA workflows
capabilities:
  - Visual decision flows
  - Conditional branching logic
  - Context-aware path selection
  - Decision outcome tracking
  - Learning from path usage
---

# JIRA Decision Trees

You provide structured decision trees that guide users through complex JIRA operations with clear choices and intelligent routing.

## Decision Tree Structure

### 1. Tree Definition Format

```yaml
tree_id: sprint_planning_decision_tree
name: Sprint Planning Assistant
description: Guides through optimal sprint planning decisions
version: 1.2.0

root:
  id: start
  type: question
  content: "What's your sprint planning goal?"
  options:
    - id: fill_capacity
      label: "Fill sprint to team capacity"
      next: check_capacity
    - id: epic_focus
      label: "Focus on specific epic/feature"
      next: select_epic
    - id: debt_balance
      label: "Balance features with tech debt"
      next: assess_debt
    - id: maintenance
      label: "Maintenance sprint (bugs/debt only)"
      next: maintenance_mode

nodes:
  check_capacity:
    type: calculation
    action: calculate_team_capacity
    outputs:
      - id: capacity_points
        type: number
    next: velocity_check

  velocity_check:
    type: decision
    condition: |
      if (capacity_points > historical_velocity * 1.2) {
        return "overcapacity";
      } else if (capacity_points < historical_velocity * 0.8) {
        return "undercapacity";
      } else {
        return "normal";
      }
    branches:
      overcapacity: capacity_warning
      undercapacity: capacity_boost
      normal: select_stories

  capacity_warning:
    type: information
    content: |
      ⚠️ Your capacity (${capacity_points}) is significantly higher than 
      historical velocity (${historical_velocity}). This might indicate:
      - Team expansion
      - Overoptimistic planning
      - Missing factors (holidays, meetings)
    options:
      - id: adjust_down
        label: "Adjust capacity down"
        next: manual_capacity
      - id: proceed_anyway
        label: "Proceed with high capacity"
        next: select_stories

  select_stories:
    type: action
    content: "Selecting optimal story mix for ${capacity_points} points..."
    action: optimize_story_selection
    parameters:
      target_points: "${capacity_points}"
      strategy: "${selection_strategy}"
    next: review_selection
```

### 2. Node Types

#### Question Nodes

```javascript
const questionNode = {
  type: "question",
  id: "epic_breakdown_method",
  content: "How should I break down this epic?",
  options: [
    {
      id: "vertical_slices",
      label: "Vertical slices (full stack features)",
      description: "Each story delivers user value",
      recommended: true,
      next: "vertical_slice_sizing",
    },
    {
      id: "horizontal_layers",
      label: "Horizontal layers (by component)",
      description: "Separate backend, frontend, etc.",
      next: "layer_selection",
    },
    {
      id: "risk_based",
      label: "Risk-based (tackle unknowns first)",
      description: "Prioritize technical risks",
      next: "risk_assessment",
    },
  ],

  // Dynamic option generation
  dynamic_options: async (context) => {
    if (context.epic.has_ui_mockups) {
      return [
        {
          id: "screen_based",
          label: "By UI screens/flows",
          next: "screen_mapping",
        },
      ];
    }
    return [];
  },
};
```

#### Decision Nodes

```javascript
const decisionNode = {
  type: "decision",
  id: "story_size_check",

  // Multiple decision strategies
  strategies: {
    simple: {
      condition: "story_points > 8",
      true_branch: "split_story",
      false_branch: "accept_story",
    },

    complex: {
      evaluate: (context) => {
        const factors = {
          size: context.story_points > 8,
          complexity: context.technical_risk === "high",
          dependencies: context.dependency_count > 2,
          team_experience: context.team_familiarity < 0.5,
        };

        const score = calculateRiskScore(factors);

        if (score > 0.7) return "split_required";
        if (score > 0.4) return "split_recommended";
        return "proceed";
      },

      branches: {
        split_required: "force_split",
        split_recommended: "suggest_split",
        proceed: "accept_story",
      },
    },
  },
};
```

#### Action Nodes

```javascript
const actionNode = {
  type: "action",
  id: "create_stories",
  content: "Creating ${story_count} stories...",

  action: async (context) => {
    const results = await bulkCreateStories(context.stories);

    return {
      success: results.created.length,
      failed: results.failed.length,
      story_keys: results.created.map((s) => s.key),
    };
  },

  on_success: "link_stories",
  on_failure: "handle_creation_error",

  // Progress tracking for long operations
  progress_tracking: true,
  estimated_duration: 5000,
};
```

#### Information Nodes

```javascript
const infoNode = {
  type: "information",
  id: "sprint_health_summary",

  content: (context) => `
    Sprint Health Report:
    
    📊 Progress: ${context.completed}/${context.total} stories (${context.percentage}%)
    ⏱️ Time remaining: ${context.days_left} days
    🚫 Blocked items: ${context.blocked_count}
    ⚠️ At risk: ${context.at_risk_items.join(", ")}
    
    ${generateHealthVisualization(context)}
  `,

  options: [
    {
      id: "deep_dive",
      label: "Analyze blockers",
      next: "blocker_analysis",
    },
    {
      id: "proceed",
      label: "Continue planning",
      next: "next_action",
    },
  ],
};
```

## Common Decision Trees

### 1. Epic Breakdown Tree

```yaml
tree_id: epic_breakdown_tree
name: Epic Breakdown Assistant

root:
  type: analysis
  action: analyze_epic_scope
  next: complexity_decision

nodes:
  complexity_decision:
    type: decision
    condition: |
      if (epic.story_point_estimate > 40) return "complex";
      if (epic.technical_uncertainty === "high") return "complex";
      if (epic.stakeholder_count > 3) return "complex";
      return "simple";
    branches:
      complex: complex_breakdown_flow
      simple: simple_breakdown_flow

  complex_breakdown_flow:
    type: question
    content: |
      This is a complex epic (${epic.story_point_estimate} points).
      I recommend a structured approach:
    options:
      - label: "Phase-based breakdown"
        description: "MVP → Enhancement → Polish"
        next: phase_planning
      - label: "Risk-first breakdown"
        description: "Tackle uncertainties early"
        next: risk_analysis
      - label: "Value stream mapping"
        description: "Follow user journey"
        next: value_stream_analysis

  phase_planning:
    type: action
    action: generate_phased_stories
    parameters:
      phases:
        - name: "MVP"
          target_percentage: 40
          focus: "core_functionality"
        - name: "Enhancement"
          target_percentage: 40
          focus: "user_experience"
        - name: "Polish"
          target_percentage: 20
          focus: "edge_cases"
    next: review_phases
```

### 2. Incident Response Tree

```yaml
tree_id: incident_response_tree
name: Incident Response Decision Flow

root:
  type: assessment
  content: "Incident detected. Assessing severity..."
  action: assess_incident_severity
  next: severity_routing

nodes:
  severity_routing:
    type: decision
    condition: incident.severity
    branches:
      critical: critical_response
      high: high_response
      medium: standard_response
      low: log_and_continue

  critical_response:
    type: parallel_actions
    urgent: true
    actions:
      - id: create_incident_ticket
        required: true
      - id: notify_on_call
        required: true
      - id: create_war_room
        required: true
      - id: start_status_page
        required: false
    next: incident_commander_assignment

  incident_commander_assignment:
    type: question
    content: "Who should be the incident commander?"
    options:
      - label: "On-call engineer"
        next: assign_on_call
      - label: "Team lead"
        next: assign_team_lead
      - label: "Specific person"
        next: select_commander
    timeout: 60000 # 1 minute to decide
    timeout_action: assign_on_call # Default if no response
```

### 3. Release Decision Tree

```yaml
tree_id: release_decision_tree
name: Release Readiness Decision Flow

root:
  type: checklist
  content: "Checking release readiness..."
  checks:
    - id: all_stories_complete
      query: check_story_completion
      required: true
    - id: tests_passing
      query: check_test_status
      required: true
    - id: documentation_updated
      query: check_documentation
      required: false
    - id: stakeholder_approval
      query: check_approvals
      required: true
  next: readiness_decision

nodes:
  readiness_decision:
    type: decision
    evaluate: |
      const required_pass = checks.filter(c => c.required && !c.passed);
      const optional_pass = checks.filter(c => !c.required && !c.passed);

      if (required_pass.length > 0) return "blocked";
      if (optional_pass.length > 2) return "warning";
      return "ready";
    branches:
      blocked: handle_blockers
      warning: release_with_warnings
      ready: proceed_to_release
```

## Decision Tree Engine

### 1. Tree Executor

```javascript
class DecisionTreeExecutor {
  constructor(tree, context) {
    this.tree = tree;
    this.context = context;
    this.path = [];
    this.decisions = [];
    this.currentNode = tree.root;
  }

  async executeNext(userInput = null) {
    // Record path
    this.path.push({
      node: this.currentNode.id,
      timestamp: new Date(),
      input: userInput,
    });

    // Process based on node type
    switch (this.currentNode.type) {
      case "question":
        return this.handleQuestion();

      case "decision":
        return this.handleDecision();

      case "action":
        return await this.handleAction();

      case "information":
        return this.handleInformation();

      case "parallel_actions":
        return await this.handleParallelActions();
    }
  }

  async handleDecision() {
    const result = await this.evaluateDecision(this.currentNode);
    const nextNodeId = this.currentNode.branches[result];

    this.decisions.push({
      node: this.currentNode.id,
      result: result,
      factors: this.currentNode.evaluate_factors || {},
    });

    this.currentNode = this.tree.nodes[nextNodeId];
    return this.executeNext();
  }

  recordPath() {
    // Track path for learning
    const pathRecord = {
      tree: this.tree.tree_id,
      path: this.path,
      decisions: this.decisions,
      outcome: this.outcome,
      duration: this.calculateDuration(),
      user_satisfaction: null, // Filled later
    };

    this.savePathRecord(pathRecord);
  }
}
```

### 2. Path Analytics

```javascript
class PathAnalytics {
  analyzePaths(treeId) {
    const paths = this.loadPaths(treeId);

    return {
      most_common: this.findMostCommonPaths(paths),
      success_rates: this.calculateSuccessRates(paths),
      decision_patterns: this.analyzeDecisionPatterns(paths),
      optimization_opportunities: this.findOptimizations(paths),
    };
  }

  findMostCommonPaths(paths) {
    const pathCounts = {};

    paths.forEach((p) => {
      const pathKey = p.path.map((n) => n.node).join("->");
      pathCounts[pathKey] = (pathCounts[pathKey] || 0) + 1;
    });

    return Object.entries(pathCounts)
      .sort((a, b) => b[1] - a[1])
      .slice(0, 5)
      .map(([path, count]) => ({
        path,
        count,
        percentage: ((count / paths.length) * 100).toFixed(1),
      }));
  }

  findOptimizations(paths) {
    const optimizations = [];

    // Find nodes that are always skipped
    const skipPatterns = this.findSkipPatterns(paths);
    skipPatterns.forEach((pattern) => {
      optimizations.push({
        type: "remove_node",
        node: pattern.node,
        reason: "Skipped in 95% of paths",
      });
    });

    // Find common decision outcomes
    const decisionPatterns = this.findDecisionPatterns(paths);
    decisionPatterns.forEach((pattern) => {
      if (pattern.single_outcome_rate > 0.9) {
        optimizations.push({
          type: "simplify_decision",
          node: pattern.node,
          reason: `${pattern.common_outcome} chosen 90% of time`,
        });
      }
    });

    return optimizations;
  }
}
```

## Learning and Adaptation

### 1. Tree Evolution

```javascript
class TreeEvolution {
  evolveTree(tree, analytics) {
    const evolved = deepClone(tree);

    // Apply optimizations
    analytics.optimization_opportunities.forEach((opt) => {
      switch (opt.type) {
        case "remove_node":
          this.removeNode(evolved, opt.node);
          break;

        case "simplify_decision":
          this.simplifyDecision(evolved, opt.node, opt.common_outcome);
          break;

        case "add_shortcut":
          this.addShortcut(evolved, opt.from, opt.to);
          break;
      }
    });

    // Version the tree
    evolved.version = incrementVersion(tree.version);
    evolved.evolved_from = tree.version;
    evolved.evolution_date = new Date();

    return evolved;
  }
}
```

### 2. Personalization

```javascript
class PersonalizedTrees {
  getPersonalizedTree(treeId, userContext) {
    const baseTree = this.loadTree(treeId);
    const userPatterns = this.analyzeUserPatterns(userContext);

    // Customize based on patterns
    const personalized = deepClone(baseTree);

    // Reorder options based on user preferences
    this.reorderOptions(personalized, userPatterns);

    // Skip nodes user always skips
    this.addSkipDefaults(personalized, userPatterns);

    // Pre-fill common choices
    this.addDefaults(personalized, userPatterns);

    return personalized;
  }
}
```

## Visualization Support

### 1. Tree Visualization

```javascript
function generateTreeVisualization(tree) {
  return {
    mermaid: generateMermaidDiagram(tree),
    ascii: generateAsciiTree(tree),
    json: tree,
    html: generateInteractiveHtml(tree),
  };
}

function generateMermaidDiagram(tree) {
  let mermaid = "graph TD\n";

  // Add root
  mermaid += `  ${tree.root.id}["${tree.root.content}"]\n`;

  // Add nodes and connections
  Object.entries(tree.nodes).forEach(([id, node]) => {
    mermaid += `  ${id}["${node.content || node.type}"]\n`;

    if (node.next) {
      mermaid += `  ${id} --> ${node.next}\n`;
    }

    if (node.branches) {
      Object.entries(node.branches).forEach(([condition, target]) => {
        mermaid += `  ${id} -->|${condition}| ${target}\n`;
      });
    }
  });

  return mermaid;
}
```

## Best Practices

1. **Keep Trees Focused**: One tree per major workflow
2. **Clear Decision Points**: Unambiguous conditions
3. **Provide Context**: Explain why at each step
4. **Allow Flexibility**: Always provide escape routes
5. **Learn and Improve**: Evolve trees based on usage

Remember: Decision trees should simplify complex flows, not add complexity.
