---
theme: ../../packages/theme
title: My AI Dev Loop
author: Erwann
colorSchema: dark
highlight: one-dark-pro
section: AI Dev Loop
description: Implement with AI, open a draft PR, triage review feedback, and fine-tune my setup — repeat
favicon: /favicon.svg
layout: cover
---

# My AI Dev Loop

Implement with AI. Review. Fine-tune. Repeat.

Erwann

---

## What this is about

<div style="--kv-value-size:26px;--kv-key-size:20px;--kv-gap:38px 32px;--kv-line-height:1.3">
<KeyValue :items="[
  { key: '😮‍💨 Before', value: 'Every step, by hand<br><span style=&quot;font-size:16px;opacity:0.5&quot;>plan · code · lint · commit · PR · Jira · Slack · review · merge</span>' },
  { key: '🧘 Now', value: 'Same steps — I supervise instead of execute' },
  { key: '🎬 Demo', value: 'From Jira ticket to draft PR — using <code>/feature-workflow</code>' },
  { key: '🔁 Loop', value: 'Each PR makes the next one faster' },
]" />
</div>

---

## 🎫 I get assigned this ticket

<div style="border:1px solid var(--color-border);border-radius:10px;padding:16px 20px;background:var(--color-card)">

<KeyValue :items="[
  { key: 'Ticket', value: 'GO-2455', badge: true },
  { key: 'Type', value: '🐛 Bug' },
  { key: 'Status', value: 'Backlog' },
  { key: 'Summary', value: '[Song] — There is a comma and decimal part for quantity of creations and playlists' },
]" />

<Callout type="note" title="Steps to reproduce" style="margin-top:12px">

1. Log in to the app
2. Open a Song page with a playlist/TikTok creations count under 1k
3. Inspect the quantity in the metrics section under the header

**AR:** There is a comma and decimal part &nbsp;·&nbsp; **ER:** No comma or decimal for quantities under 1k

</Callout>

</div>

> Now what?

---

## Without AI

<div style="display:flex;gap:40px;align-items:stretch">
<div style="flex:1">

<Timeline :compact="true" :items="[
  { date: '', title: '🧠 Plan', description: 'Read the ticket, figure out where to start' },
  { date: '', title: '🔨 Build', description: 'Create branch, write code, fix lint, run tests' },
  { date: '', title: '📝 Commit & PR', description: 'Format the commit, fill the PR template from scratch' },
  { date: '', title: '🔍 Self-review', description: 'PR is in draft — my own code review, fix what I disagree with' },
  { date: '', title: '📣 Notify', description: 'Un-draft the PR, update Jira, post in Slack, request reviewers' },
  { date: '', title: '💬 Review', description: 'Read feedback, make changes, re-notify the team' },
  { date: '', title: '🚀 Merge', description: 'Check CI, squash merge, close ticket, post again' },
]" />

</div>
<img src="./without-ai.jpg" style="width:420px;border-radius:12px;object-fit:cover;align-self:stretch" />
</div>

---

## With AI

<div style="display:flex;gap:40px;align-items:stretch">
<div style="flex:1">

<Timeline :compact="true" :items="[
  { date: '', title: '🧠 Plan', description: 'Read the ticket, paste the link to <code>/feature-workflow</code> — planner proposes an approach, I agree or tweak it' },
  { date: '', title: '🤖 Build', description: '<code>/feature-workflow</code> — branch, code, lint, tests' },
  { date: '', title: '📝 Commit & PR', description: '<code>/feature-workflow</code> — commit + draft PR, ticket ID everywhere' },
  { date: '', title: '🔍 Self-review', description: 'PR is in draft — my own code review, ask AI to fix what I disagree with' },
  { date: '', title: '📣 Notify', description: '<code>/pr-ready</code> — un-drafts PR, GitHub, Jira, Slack' },
  { date: '', title: '💬 Review', description: 'Triage feedback, AI implements, review the diff' },
  { date: '', title: '🚀 Merge', description: '<code>/pr-finalise</code> — CI check, squash merge' },
]" />

</div>
<img src="./with-ai.webp" style="width:420px;max-height:340px;border-radius:12px;object-fit:cover;align-self:center" />
</div>

---

## Same loop. I just supervise it now.

<style>
.mermaid .cluster-label span { font-size: 15px !important; font-weight: 700 !important; }
</style>

<div style="font-size:11px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:6px">Without AI</div>

```mermaid
%%{init:{'theme':'dark','themeVariables':{'primaryColor':'#4c9eb2','primaryTextColor':'#fff','primaryBorderColor':'#4c9eb2','lineColor':'#4c9eb2','clusterBkg':'#0d1f2d','clusterBorder':'#4c9eb2','fontFamily':'JetBrains Mono, monospace','fontSize':'13px'}}}%%
flowchart LR
    subgraph me ["🙋 Me — everything"]
        direction LR
        A(["Plan (45m)"]) --> B(["Build (2h30m)"]) --> C(["Commit & PR (10m)"]) --> D(["Notify (2m)"]) --> E(["Review (30m)"]) --> F(["Merge (3m)"])
    end
    F --> Z(["⏱ ~4h"])
    style A fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style B fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style C fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style D fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style E fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style F fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style Z fill:#f59e0b,color:#fff,stroke:#f59e0b
```

<div style="font-size:11px;font-weight:700;color:#10b981;text-transform:uppercase;letter-spacing:0.06em;margin-top:16px;margin-bottom:6px">With AI</div>

```mermaid
%%{init:{'theme':'dark','themeVariables':{'primaryColor':'#4c9eb2','primaryTextColor':'#fff','primaryBorderColor':'#4c9eb2','lineColor':'#4c9eb2','clusterBkg':'#0d1f2d','clusterBorder':'#4c9eb2','fontFamily':'JetBrains Mono, monospace','fontSize':'13px'}}}%%
flowchart LR
    subgraph ai ["🤖 AI"]
        B(["Plan"])
        D(["Build & PR"])
        F(["Notify"])
        H(["Implement & Merge"])
    end
    subgraph me ["🧘 Me"]
        A(["Paste ticket (2m)"])
        C(["Approve plan (10m)"])
        E(["Self-review (15m)"])
        G(["Triage feedback (15m)"])
    end
    A-->B-->C-->D-->E-->F-->G-->H
    G --> ZM(["⏱ ~45m"])
    style A fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style C fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style E fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style G fill:#4c9eb2,color:#fff,stroke:#4c9eb2
    style B fill:#10b981,color:#fff,stroke:#10b981
    style D fill:#10b981,color:#fff,stroke:#10b981
    style F fill:#10b981,color:#fff,stroke:#10b981
    style H fill:#10b981,color:#fff,stroke:#10b981
    style ZM fill:#f59e0b,color:#fff,stroke:#f59e0b
```

---

## 🧩 Before we start

<div style="font-size:14px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:10px">Terminology</div>

<KeyValue :items="[
  { key: 'MCP', value: 'Connectors that give Claude knowledge from external services — Atlassian for Jira, GitHub for PRs.' },
  { key: 'Skill', value: 'A <code>/command</code> that orchestrates a full workflow — scoping, planning, implementing, shipping.' },
  { key: 'Agent', value: 'A specialist Claude instance with a defined role and model — invoked by skills to do one thing well.' },
]" />

<hr style="border:none;border-top:1px solid var(--color-border);margin:18px 0" />

<div style="font-size:14px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:10px">Needed for this demo</div>

<KeyValue :items="[
  { key: 'Atlassian MCP', value: 'Read the Jira ticket &amp; transition its status' },
  { key: 'GitHub MCP', value: 'Open the draft PR &amp; request reviewers' },
  { key: '<code>/feature-workflow</code>', value: 'The skill that orchestrates it all' },
]" />

---
layout: section
---

# 🎬 Live Demo

<img src="./cat-coding.gif" style="position:absolute;right:48px;top:50%;transform:translateY(-50%);border-radius:12px;height:420px" />

---

## 🎯 Let's try with this

<KeyValue :items="[
  { key: 'Ticket', value: 'GO-2455', badge: true },
  { key: 'Summary', value: '[Song] There is a comma and decimal part for quantity of creations and playlists' },
  { key: 'Link', value: '<a href=&quot;https://theorchard.atlassian.net/browse/GO-2455&quot; target=&quot;_blank&quot;>theorchard.atlassian.net/browse/GO-2455</a>' },
]" />


---

## `/feature-workflow` — nine agents

<div style="display:flex;gap:40px;align-items:stretch">
<div style="flex:1;display:flex;flex-direction:column">

<Timeline :compact="true" :extend-last="true" :items="[
  { date: '', title: '🔍 Scope', description: 'Flags missing requirements &amp; open questions before any code is written — Name: <code>scoper</code> Model: <code style=&quot;color:#10b981&quot;>Sonnet</code>' },
  { date: '', title: '🧠 Plan', description: 'Explores codebase, maps the approach — I review and approve before a line is written — Name: <code>planner</code> Model: <code style=&quot;color:#ef4444&quot;>Opus</code>' },
  { date: '', title: '🌿 Branch', description: 'Checks out <code>GO-XXXX/short-description</code> — ticket ID baked in from the start — Name: <code>brancher</code> Model: <code style=&quot;color:#22d3ee&quot;>Haiku</code>' },
  { date: '', title: '🔨 Implement', description: 'Writes code from the approved plan — meaningful names, minimal scope, no comments — Name: <code>implementer</code> Model: <code style=&quot;color:#10b981&quot;>Sonnet</code>' },
]" />

</div>
<div style="flex:1">

<Timeline :compact="true" :items="[
  { date: '', title: '🧪 Tests', description: 'Evaluates if tests are needed, writes Jest unit/integration tests pinned to the ticket — Name: <code>test-writer</code> Model: <code style=&quot;color:#10b981&quot;>Sonnet</code>' },
  { date: '', title: '✅ Lint &amp; Test', description: 'Runs in parallel, auto-fixes errors — loops up to 3 times before stopping — Name: <code>linter</code> + <code>tester</code> Model: <code style=&quot;color:#10b981&quot;>Sonnet</code>' },
  { date: '', title: '📝 Commit', description: 'Formats <code>GO-XXXX: 🐛 fix(scope): ...</code> — ticket ID first, gitmoji convention — Name: <code>committer</code> Model: <code style=&quot;color:#22d3ee&quot;>Haiku</code>' },
  { date: '', title: '📬 PR', description: 'Fills repo PR template, opens as draft — ready for my review before going public — Name: <code>pr-opener</code> Model: <code style=&quot;color:#10b981&quot;>Sonnet</code>' },
  { date: '', title: '📋 Summary', description: 'Technical handoff: what changed, how to validate, any follow-ups — Name: <code>summariser</code> Model: <code style=&quot;color:#22d3ee&quot;>Haiku</code>' },
]" />

</div>
</div>

<div style="margin-top:14px">
<Callout type="tip" title="Cost intentionality">
<code style="color:#ef4444">Opus</code> only where reasoning depth matters (planning) · <code style="color:#10b981">Sonnet</code> for implementation & writing · <code style="color:#22d3ee">Haiku</code> for mechanical tasks (branch, commit, summarise)
</Callout>
</div>

---

## 🔍 Review the draft

PR is in draft. My turn — I decide if it ships.

- 🧠 Does the code make sense?
- ✅ Do the tests cover the right cases?
- 📱 Does it work? I test on the simulator or the browser
- 🚦 Only I un-draft it — I give the green light when it's ready for the team

<img src="./review-draft.jpg" style="margin-top:12px;width:380px;border-radius:12px;display:block;margin-left:auto;margin-right:auto" />

---

## `/pr-ready`

Once I'm happy with the draft, one command handles all the handoff.

| Service | Action |
|---|---|
| GitHub | Draft → ready for review |
| Jira | In Development → Code Review |
| Slack | Team notified |

<img src="./slack-pr-ready.png" style="margin-top:16px;border-radius:8px" />

---

## 💬 Handle team feedback

- 📖 Read each reviewer comment
- 🤔 I decide: accept, push back, or ask for clarification — AI doesn't triage for me
- 🧘 Once I have a clear vision, I ask AI to fix it the way I think it should be
- 🔍 Review the diff before re-requesting review — I approve every change that goes out

<img src="./team-feedback.jpg" style="margin-top:16px;width:420px;border-radius:12px;display:block;margin-left:auto;margin-right:auto" />

---

## `/pr-finalise`

Once the team has approved and CI is green, one command closes the loop.

<Callout type="warning" title="Gates">
CI green &nbsp;·&nbsp; required approvals (GitHub branch rules) &nbsp;·&nbsp; not in draft
</Callout>

| Service | Action |
|---|---|
| GitHub | Squash merge |
| Jira | Code Review → UAT |
| Slack | Merge notification sent |

---

## ✅ What `/feature-workflow` produces for GO-2455

<Timeline :bare="true" :items="[
  { date: 'Branch', title: 'GO-2455/fix-song-metrics-number-format', description: '' },
  { date: 'Commit', title: 'GO-2455: 🐛 fix(song): remove comma and decimal for counts under 1k', description: '' },
  { date: 'PR', title: 'GO-2455: 🐛 fix(song): remove comma and decimal for counts under 1k', description: 'Draft — opened against main' },
  { date: 'Jira', title: 'Ready for Dev → In Development', description: '' },
]" />

---
layout: section
---

# The Postmortem
## Close the loop

---

## `/pr-postmortem`

Summarises patterns from all review comments, then suggests where to apply them:

| Where | What to update |
|---|---|
| `CLAUDE.md` | Coding conventions the AI must follow |
| Skills | Prompts that drive individual workflows |
| Agents | Behaviour of specialist agents |

One postmortem → concrete suggestions ready to apply.

---

## 📉 The compound effect of using AI well

<div style="display:flex;gap:12px;align-items:stretch;margin-bottom:14px">
  <div style="flex:1;padding:10px 14px;background:rgba(76,158,178,0.08);border:1px solid rgba(76,158,178,0.2);border-radius:8px">
    <div style="font-size:10px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:4px">Phase 1 — Autonomous</div>
    <div style="font-size:12px;opacity:0.8">🤖 Fully autonomous · team overwhelmed · noisy PRs · inconsistent quality</div>
  </div>
  <div style="display:flex;align-items:center;font-size:18px;opacity:0.4">→</div>
  <div style="flex:1;padding:10px 14px;background:rgba(76,158,178,0.04);border:1px solid rgba(76,158,178,0.15);border-radius:8px">
    <div style="font-size:10px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:4px">Phase 2 — Supervised</div>
    <div style="font-size:12px;opacity:0.8">🧘 Each review comment becomes a rule · standards compound PR by PR</div>
  </div>
</div>

<svg width="460" height="190" viewBox="0 0 460 190" style="overflow:visible;display:block;font-size:0">
  <defs>
    <linearGradient id="chartGrad" x1="0" y1="0" x2="0" y2="1">
      <stop offset="0%" stop-color="#4c9eb2" stop-opacity="0.3"/>
      <stop offset="100%" stop-color="#4c9eb2" stop-opacity="0.02"/>
    </linearGradient>
  </defs>
  <line x1="15" y1="59" x2="445" y2="59" stroke="#ffffff" stroke-opacity="0.06" stroke-width="1"/>
  <line x1="15" y1="93" x2="445" y2="93" stroke="#ffffff" stroke-opacity="0.06" stroke-width="1"/>
  <line x1="15" y1="126" x2="445" y2="126" stroke="#ffffff" stroke-opacity="0.06" stroke-width="1"/>
  <line x1="15" y1="160" x2="445" y2="160" stroke="#ffffff" stroke-opacity="0.12" stroke-width="1"/>
  <path d="M15,39 C68.75,39 68.75,66 122.5,66 C176.25,66 176.25,93 230,93 C283.75,93 283.75,120 337.5,120 C391.25,120 391.25,147 445,147 L445,160 L15,160 Z" fill="url(#chartGrad)"/>
  <path d="M15,39 C68.75,39 68.75,66 122.5,66 C176.25,66 176.25,93 230,93 C283.75,93 283.75,120 337.5,120 C391.25,120 391.25,147 445,147" stroke="#4c9eb2" stroke-width="2.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/>
  <circle cx="15" cy="39" r="6" fill="#4c9eb2" fill-opacity="0.2"/>
  <circle cx="122.5" cy="66" r="6" fill="#4c9eb2" fill-opacity="0.2"/>
  <circle cx="230" cy="93" r="6" fill="#4c9eb2" fill-opacity="0.2"/>
  <circle cx="337.5" cy="120" r="6" fill="#4c9eb2" fill-opacity="0.2"/>
  <circle cx="445" cy="147" r="6" fill="#4c9eb2" fill-opacity="0.2"/>
  <circle cx="15" cy="39" r="3.5" fill="#4c9eb2"/>
  <circle cx="122.5" cy="66" r="3.5" fill="#4c9eb2"/>
  <circle cx="230" cy="93" r="3.5" fill="#4c9eb2"/>
  <circle cx="337.5" cy="120" r="3.5" fill="#4c9eb2"/>
  <circle cx="445" cy="147" r="3.5" fill="#4c9eb2"/>
  <text x="15" y="28" text-anchor="middle" fill="#ffffff" fill-opacity="0.6" style="font-size:11px;font-family:JetBrains Mono,monospace">18</text>
  <text x="122.5" y="55" text-anchor="middle" fill="#ffffff" fill-opacity="0.6" style="font-size:11px;font-family:JetBrains Mono,monospace">14</text>
  <text x="230" y="82" text-anchor="middle" fill="#ffffff" fill-opacity="0.6" style="font-size:11px;font-family:JetBrains Mono,monospace">10</text>
  <text x="337.5" y="109" text-anchor="middle" fill="#ffffff" fill-opacity="0.6" style="font-size:11px;font-family:JetBrains Mono,monospace">6</text>
  <text x="445" y="136" text-anchor="middle" fill="#ffffff" fill-opacity="0.6" style="font-size:11px;font-family:JetBrains Mono,monospace">2</text>
  <text x="15" y="176" text-anchor="middle" fill="#ffffff" fill-opacity="0.4" style="font-size:10px;font-family:JetBrains Mono,monospace">PR 1</text>
  <text x="122.5" y="176" text-anchor="middle" fill="#ffffff" fill-opacity="0.4" style="font-size:10px;font-family:JetBrains Mono,monospace">PR 5</text>
  <text x="230" y="176" text-anchor="middle" fill="#ffffff" fill-opacity="0.4" style="font-size:10px;font-family:JetBrains Mono,monospace">PR 10</text>
  <text x="337.5" y="176" text-anchor="middle" fill="#ffffff" fill-opacity="0.4" style="font-size:10px;font-family:JetBrains Mono,monospace">PR 20</text>
  <text x="445" y="176" text-anchor="middle" fill="#ffffff" fill-opacity="0.4" style="font-size:10px;font-family:JetBrains Mono,monospace">PR 50</text>
</svg>

<div style="margin-top:16px;padding:12px 16px;border-left:3px solid var(--color-accent);opacity:0.7">

Every postmortem + fine-tuning cycle should push the curve down.<br>
Not because the AI got smarter — <strong>because I taught it my standards.</strong>

</div>
<div style="font-size:11px;color:var(--color-accent);margin-top:8px;opacity:0.6">Goal projection — not measured data</div>

---

## 🧠 What I get back

<div style="display:flex;gap:48px;margin-top:8px">

<div style="flex:1">
  <div style="font-size:11px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:14px">Without AI — my time goes to</div>

  - ⏱️ Writing the code, fixing lint, running tests
  - ⏱️ Naming branches correctly
  - ⏱️ Formatting commit messages
  - ⏱️ Filling PR templates
  - ⏱️ Updating Jira, posting in Slack
  - ⏱️ Re-notifying reviewers

  **Every. Single. PR.**

</div>

<div style="flex:1">
  <div style="font-size:11px;font-weight:700;color:var(--color-accent);text-transform:uppercase;letter-spacing:0.06em;margin-bottom:14px">With AI — my time goes to</div>

  - 🏗️ Architecture & system design
  - 🗺️ Planning & breaking down problems
  - 🔍 Code review — catching what matters
  - 💬 Collaborating on trade-offs
  - 🌱 Learning from the code, not wrestling with CI and PR templates

</div>

</div>

---
layout: cover
---

# Every PR makes the next one faster.

Erwann

<img src="./closing.jpg" style="position:absolute;right:48px;top:50%;transform:translateY(-50%);height:220px;border-radius:12px;object-fit:cover" />
