System Architecture
Code Mint automates Jira-to-PR workflow using Claude CLI for AI-powered code generation.
┌─────────┐    ┌──────────────┐    ┌─────────────┐    ┌──────────┐
│  Jira   │───>│  Webhook       │───>│ Orchestrator │───>│ Claude   │
│ Webhook │    │  Server        │    │             │    │ CLI      │
└─────────┘    └──────────────┘    └──────┬──────┘    └────┬─────┘
                                                    │                  │
                                             ┌──────┴──────┐   ┌─────┴─────┐
                                             │ Context      │   │ Git Manager│
                                             │ Gatherer     │   │ + Bitbucket│
                                             └──────────────┘   └────────────┘
Processing Pipeline
┌─────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐
│ WEBHOOK │────>│ CONTEXT  │────>│ CLARIFY  │────>│  CLONE   │────>│ CODEGEN  │
│ receive │     │ gather   │     │ (if need)│     │ repo     │     │ Claude   │
└─────────┘     └──────────┘     └──────────┘     └──────────┘     └────┬─────┘
                                                                          │
┌─────────┐     ┌──────────┐     ┌──────────┐     ┌──────────┐         │
│ LEARN   │<────│  JIRA    │<────│   PR     │<────│ VALIDATE │<─────────┘
│ record  │     │ comment  │     │ create   │     │ test/lint│
└─────────┘     └──────────┘     └──────────┘     └──────────┘
~50ms   |   2-5s   |   1-2min   |   2-30s   |   2-8min   |   10s-2min   |   1-2s   |   500ms   |   50ms
Module Reference
Module Purpose
webhook_server.pyFastAPI server, webhook handlers (Jira + Bitbucket)
orchestrator.pyMain process_ticket() coordination
context_gatherer.pyEnrich tickets with epic, links, comments
learning_store.pyRecord implementations, find similar tickets
db.pyPostgreSQL ORM models and store
postgres_store.pyOptional PostgreSQL store for metadata
repo_router.pyDetermine target repositories
plan_store.pyManage pending implementation plans
agent.pyPlan extraction, session reading, Claude API fallback
git_utils.pyGit clone, branch, commit, push
bitbucket_client.pyBitbucket PR creation
jira_client.pyJira API operations
config.pyConfiguration loading and validation
models.pyPydantic models for all data structures
prompts.pyAll prompts for Claude interactions
Work Directory Structure
~/.jira-automation/
├── webhook_logs/           # Incoming webhook payloads
│   └── {TIMESTAMP}_{KEY}_{EVENT}.json
├── jobs/                   # Job metadata (Postgres primary)
│   └── {TICKET-ID}.json
├── plans/                  # Implementation plans
│   └── {TICKET-ID}_v{N}.md
├── job_logs/               # Per-job log files
│   └── {JOB-ID}.log
├── learning/               # Continuous learning
│   ├── index.jsonl         # Grep-searchable index
│   └── records/
│       ├── {TICKET}.json   # Structured record
│       └── {TICKET}/
│           └── outcome.md  # Agent-readable markdown
├── {repo}/                 # Main clone (shared)
└── {repo}-worktrees/       # Per-ticket isolation
    └── {TICKET}/
Integration Architecture
Jira REST API (Basic Auth)
  • GET /issue/{id} — Epic, links
  • GET /issue/{id}/comment — Comments
  • GET /issue/{id}/remotelink — Confluence/Figma
  • POST /issue/{id}/comment — Post results
  • PUT /issue/{id} — Add labels
Bitbucket REST API (Bearer token)
  • POST /pullrequests — Create PR
  • GET /pullrequests?q= — Find existing
  • git clone/push — HTTPS Basic Auth
Claude CLI (OAuth)
  • --permission-mode plan — Read-only phases
  • --dangerously-skip-permissions — Code gen
  • --resume {id} — Session continuity
  • --add-dir — Learning, context, repos
Confluence (Basic Auth, optional)
  • GET /content/{id} — Fetch page body
Concurrency & Isolation
Worktree Strategy
Main Clone ({repo}/.git)
  ├── git worktree add ──> {repo}-worktrees/PROJ-123/
  ├── git worktree add ──> {repo}-worktrees/PROJ-456/
  └── git worktree add ──> {repo}-worktrees/PROJ-789/
Deduplication Flow
Webhook ──> Auto-code label? ──NO──> Reject (skip cache)
              │
             YES
              │
        PostgreSQL? ──YES──> try_acquire_lock (10s)
              │                    │
             NO                ┌─────┴─────┐
              │           acquired    not acquired
        In-memory cache             │         │
        (10s window)         Running?   SKIP: dup
          │      │               │
       unique  duplicate      ┌────┴────┐
          │      │           YES       NO
       Running? SKIP        SKIP    Continue
Learning Feedback Loop
┌─ Code Generation ───────────────────┐
│  Prompt Builder ──> Claude CLI    │
│       ↑                    │      │
│  Agent searches            │      │
│  learning/ via grep        ↓      │
└─────────────────> PR + Output ─┘
                          │
                          ↓
           ┌─ Learning Store ────────┐
           │  JSON Record           │
           │  outcome.md            │
           │  index.jsonl ─────────│──> grep similar ──> next generation
           └───────────────────────┘
How agents use learnings:
  1. Learning directory injected via --add-dir learning/
  2. Agent runs grep "payment" learning/index.jsonl
  3. Agent reads cat learning/records/PROJ-123/outcome.md
  4. Past patterns inform current code generation
Architecture Decisions
Single Session over Parallel Subagents
~1,500 LOC deleted
Replaced multiple parallel Claude subagents with single-session processing.
> "Complexity is not sophistication."
Agent-Searchable Files over Pre-Injected Context
3 modules deleted
Mount directories via --add-dir instead of classifying and pre-injecting context.
> "Give agents tools instead of pre-chewing their food."
JSON Structured Output over Marker Parsing
Switched from regex-parsed ### FILE: markers to CodeGenOutput JSON.
> "Parse only what the system needs for routing."
Independent Review over Self-Review
Separate read-only Claude session with no memory of generation.
> "Verification must be structurally independent from creation."
LLM-Powered Clarification over Static Rules
LLM reasons about the ticket in context of the target repo.
> "If the decision requires judgment, use a model that can exercise judgment."
Centralized Prompts over Scattered Strings
All prompts in prompts.py. Single source of truth.
> "Prompts are code. Treat them with the same discipline."
Multi-Tag Classification over Single Enum
LLM generates tags: list[str] instead of single classification.
> "Don't force false choices in classification."
PostgreSQL with JSON Fallback
PostgreSQL as primary for row-level dedup locking. JSON files as fallback.
> "Build for the deployment model you're heading toward."
Git Worktrees for Isolation
Each ticket gets an isolated worktree from a shared main clone.
> "Filesystem isolation beats branch-based isolation."
Design Principles
01. Remove logic, add tools — Strip orchestrator-driven decision-making.
02. Agent-searchable over pre-injected — Mount files, don't stuff prompts.
03. Single code path — One flow for single-repo and multi-repo.
04. Fail open, log everything — Non-critical failures log warnings.
05. Structural independence — Verification separate from creation.
06. Session continuity — One conversation per ticket.
07. File-based simplicity — Raw markdown, JSONL, JSON. No custom formats.