196 lines
Engineering Intelligence

Solution Page

Sprint Review Analysis

Connect Jira and GitHub signals into sprint health, ghost work detection, and project-level delivery reporting.

Engineering managers
Product leaders
CTOs
Jira
GitHub
Sprint health

Overview

For Engineering managers, Product leaders, CTOs

Integrations: Jira, GitHub, Sprint health

Sprint health summary

Ghost work detection

Delivery report

Improves sprint retrospectives with evidence.

Helps product and engineering align on actual delivery.

Reduces manual review work across multiple systems.

What It Solves

Sprint reviews often miss the gap between ticket movement and actual delivery work across engineering systems.

Workflow

1

Collect delivery signals from Jira and GitHub.

2

Reconcile planned work against code activity and execution patterns.

3

Publish a sprint-level view of progress, drift, and ghost work.

Implementation

Review the underlying plan definition, inspect the template when available, and see how the workflow is encoded for repeatable execution.

Plan Code

Markdown Report

sprint-review.yaml

196 lines

transformers:
  - name: cleanup_github
    onFunctionOutput: search_pull_requests
    jmesPath: 'items[*].{title: title, state: state, url: html_url, author: user.login}'
  
  - name: cleanup_jira
    onFunctionOutput: jira_search
    jmesPath: |-
      issues[*].{
        key: key,
        summary: summary,
        status: status.name,
        status_category: status.category,
        assignee: assignee.display_name || 'Unassigned',
        project: project.key,
        priority: priority.name

      }

components:
  schemas:
    ticket:
      type: object
      required: [key, summary, status, assignee, status_category, project ]
      properties:
        key: { type: string, description: "JIRA Issue Key (e.g., PROJ-123)" }
        summary: { type: string, description: "Brief summary of the JIRA issue" }
        status: { type: string, description: "Display name of the status (e.g., To Do, In Progress, Done)" }
        status_category: { type: string, description: "High-level category used for grouping/filtering (To Do, In Progress, Done)" }
        assignee: { type: string, description: "Name of the person assigned to the issue" }
        project: { type: string, description: "JIRA project key, derived from the issue key prefix (e.g., PROJ)" }
        priority: { type: string, description: "Priority level of the issue (e.g., High, Medium, Low)" }
    
    pull_request:
      type: object
      required: [title, state, url, author]
      properties:
        title: { type: string, description: "Title of the pull request" }
        state: { type: string, description: "State of the pull request (e.g., open, closed, merged)" }
        url: { type: string, description: "URL of the pull request" }
        author: { type: string, description: "GitHub username of the PR author" }

preCalls:
  - name: search_pull_requests
    in: context
    var: github_data
    args:
      query: "org:barndoor-ai is:pr is:merged"
      per_page: 50

  - name: jira_search
    in: context
    var: jira_data
    args:
      jql: "project IN (BCP, MODA, TES, VENN) AND updated >= -60d ORDER BY updated DESC"
      fields: "priority,issuetype,labels,created,status,summary,updated,reporter,assignee,description, project"
      limit: 250
      start_at: 0


sessions:

  project_analysis:

    prompt: |-
      === github_data ===
      ```json
      {{ json .context.github_data }}
      ```
      === jira_data ===
      ```json
      {{ json .context.jira_data }}
      ```
      Analyze the JIRA data and the GitHub PRs and map to the project_analysis schema.
      
      
  github_insights:
    prompt: |-
      === github_data ===
      ```json
      {{ json .context.github_data }}
      ```

      Analyze the GitHub pull request data. 
      
      1. Count the total number of merged PRs.
      2. Identify any potential 'Ghost Work' by flagging PRs that do not have a JIRA ticket key in the title (e.g., PROJ-123).
      3. For each 'Ghost Work' PR, generate a warning message that includes the PR title, author, and URL.


  resource_health:
    prompt: |-
      === github_data ===
      ```json
      {{ json .context.github_data }}
      ```
      Analyze the GitHub PR data to assess team workload.
      
      1. Calculate a busy factor (average PRs per author).
      2. Identify overloaded contributors (more than 5 PRs).
      3. List the GitHub usernames of overloaded contributors.

  compute-analysis:
    prompt: |-
      === github_data ===
      ```json
      {{ json .context.github_data }}
      ```
      === jira_data ===
      ```json
      {{ json .context.jira_data }}
      ```
      
      Analyze the combined insights from the JIRA and GitHub data to produce a strategic report for executive leadership.
      The report should include:
      1. An executive thesis that synthesizes the core argument derived from the data analysis.
      2. An assessment of whether the product roadmap is at risk based on the analysis.
      3. A summary of key accomplishments from the engineering activity.
      4. A summary of any unresolved blockers or risks identified in the analysis.
      5. A mapping of JIRA tickets to their associated PRs, if any, to illustrate the connection between work items and code changes.


schema:
  type: object
  properties:
    github_data:
      type: array
      items:
        $ref: "#/components/schemas/pull_request"
        
    jira_data:
      type: array
      items:
        $ref: "#/components/schemas/ticket"

    github_insights:
      type: object
      x-session: github_insights
      properties:
        merged_pr_total: { type: integer }
        ghost_work_warnings:
          type: array
          items: { type: string, description: "Warning message about potential ghost work PRs without JIRA tracking" }
        unmatched_prs:           
          type: array
          items:
            type: object
            properties:
              title: { type: string, description: "Title of the pull request" }
              url: { type: string, description: "URL of the pull request" }
              author: { type: string, description: "GitHub username of the PR author" }
              state: { type: string, description: "State of the pull request (e.g., open, closed, merged)" }
        
      
    resource_health:
      x-session: resource_health
      type: object
      properties:
        busy_factor: { type: number }
        overloaded_heroes: 
          type: array
          items: { type: string, description: "GitHub username of overloaded contributor" }

    project_analysis:
      x-session: project_analysis
      type: array
      items:
        type: object
        properties:
          project: { type: string, description: "JIRA project key" }
          healthy: { type: integer, description: "1 if project has completed tickets, else 0" }
          completed_count: { type: integer, description: "Number of completed tickets in the project" }
          pending_count: { type: integer, description: "Number of pending tickets in the project" }
          merged_prs: { type: integer, description: "Number of merged PRs associated with the project" }
    
    
    strategic_report:
      type: object
      x-session: compute-analysis
      properties:
        executive_thesis:
          type: object
          properties:
            core_argument: { type: string, description: "The main insight derived from the data analysis" }
            roadmap_at_risk: { type: boolean, description: "Indicates if the product roadmap is at risk based on the analysis" }
            accomplishments: { type: string, description: "Summary of key accomplishments from the engineering activity" }
            unresolved_blockers: { type: string, description: "Summary of any unresolved blockers or risks identified in the analysis" }
        ticket_pr_map:         
          type: array
          items:
            type: object
            properties:
              ticket_key: { type: string, description: "JIRA Project key (e.g., PROJ-123)" }
              pr_urls: 
                type: array
                items: { type: string, description: "URL of the pull request associated with the ticket" }