CASE STUDY

Automated Jira-Ticket-to-Pull-Request System

4 min read·640 words·Advanced

Asked at

1 candidate report in Jun 2026

How to use this case study

SDE-2 / Mid

Explain the flow from a labeled Jira ticket to an AI agent that edits code in a sandbox, runs tests and opens a pull request.

SDE-3 / Senior

Go deeper on the job queue and workers, sandbox isolation, idempotency (no duplicate PRs), status updates back to Jira, and retries.

Staff / Principal

Discuss secrets and permissions, concurrency limits per repo, cost control, quality gates (tests, reviews) and measuring success.


0) Problem Restatement

Snowflake asked: design a system that watches Jira tickets and automatically produces pull requests (PRs). When a ticket is labeled (e.g., auto-fix), an AI coding agent checks out the repository, implements the change, runs tests, and opens a PR linked to the ticket. Many tickets can be processed at once, each in an isolated sandbox, with no duplicate PRs and clear status reporting. The interviewer's focus: async job processing and queue-based architecture.


1) Requirements

  • Trigger from Jira (webhook when a label is added, or a comment command).
  • Run each job in an isolated sandbox with the repo checked out.
  • The agent edits code, runs tests and lint, and iterates up to limits.
  • Open a PR (with the description and test results), link it to the ticket, and comment on Jira.
  • Retries on transient failures, and escalation to humans on failure.
  • Never create duplicate PRs for the same ticket.


2) Architecture

Architecture Diagram

flowchart LR
    JIRA["Jira webhook"] --> IN["Intake service - verify, dedupe"]
    IN --> DB[("Jobs DB - one active job per ticket")]
    IN --> Q[("Job queue")]
    Q --> W["Worker pool"]
    W --> SB["Sandbox - container/microVM per job"]
    SB --> REPO["Git host - clone, branch, push"]
    SB --> LLM["LLM agent"]
    SB --> CI["Tests / lint"]
    W --> DB
    W -->|"open PR"| REPO
    W -->|"status comments"| JIRA

3) Job Lifecycle

received → queued → running → (tests_passed → pr_opened) | failed | needs_human
  1. Intake: verify the webhook signature, fetch the ticket, and check eligibility (right project, has a description, repo mapping known). Create a job with a unique constraint on (ticket_id, active), so a second webhook for the same ticket doesn't create a second job. That's idempotency.
  2. Queue: jobs wait with a priority. Concurrency limits apply per repo (avoid 20 agents fighting over one repo) and overall (cost and GPU/LLM quotas).
  3. Worker leases a job (with heartbeats, as in any job scheduler) and starts a fresh sandbox: clone the repo, create the branch auto/JIRA-123, and install dependencies from a cache.
  4. Agent loop: the LLM reads the ticket and code, proposes edits, runs tests and lint in the sandbox, and fixes failures. It's bounded by time, steps and token budget.
  5. Result: if the tests pass, push the branch and open (or update, if a PR for this branch already exists) the PR with a summary, then comment the link on Jira. If it fails, comment the reason and logs, and set needs_human.


4) Reliability and Idempotency

  • Duplicate webhooks → deduplicated at intake (by event ID plus the one-active-job-per-ticket rule).
  • Worker crash → the lease expires and the job is retried in a new sandbox. The PR step is idempotent: look up an existing PR by branch name before creating one.
  • Retries with backoff for transient errors (Git, LLM rate limits). Permanent errors → fail fast with a clear message.
  • Ticket updated while a job runs → cancel and restart, or let the job finish and note that the ticket changed.


5) Security

  • Sandboxes: no access to production, limited network egress (only Git, package mirrors and the LLM API), ephemeral and destroyed after the job.
  • Scoped credentials: a short-lived token that can only push branches to that repo and open PRs. It cannot merge.
  • Secrets never go into prompts or logs. Humans review and merge every PR (a quality gate), and CI runs normally on the PR.


6) Measuring Success

PR acceptance rate, time from ticket to PR, reviewer edits needed, test pass rate, cost per job, and failure reasons (to improve prompts and tooling).


7) Wrap-Up

Receive Jira webhooks through an intake service that verifies them and creates one active job per ticket (idempotently), queue jobs with per-repo and global concurrency limits, and let leased workers run each job in a fresh, locked-down sandbox where an LLM agent edits code and runs tests within budgets. Push a branch and open or update a single PR with scoped, merge-less credentials, report status back to Jira, retry transient failures, escalate the rest to humans, and track acceptance and cost.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →