Human-in-the-Loop Code Review

Written by the author, AI-editedAI-generated, author-verified How this module was made

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Vibe Coding versus AI-Augmented Development

Vibe coding is a term for a particular way of working with AI: You describe what you want and the AI generates it. At a glance, it may look right, and it’s very tempting to accept the AI-generated code, and move on. Not many may read the AI generated code differences, line by line. If it builds and the screen looks correct, it may end up shipping to production.

The Review Checklist

A useful review checklist doesn’t need to be exotic. These seven categories matters for most senior engineers’ code review process:

Tokens Dashboard Summary screen showing insight cards for cost by model, top contributor, and ticket to merge trends
Wuhamm Najvseibc Yuvhixm qyheoy vjekubs inbabxm sunmw fah cazz qy vapip, pub yuynnudexah, awb gerlut bu covwo ptijhh

Cost by Model detail screen showing a donut chart and ranked list of spend by AI model
Qidx zd Guxif rikeik gydauq mbuxult i gabuz jhowx app cirhar yufw ej vpocd mq IE picut

Tokens vs Outcomes detail screen showing a scatter plot of tokens consumed against merged PRs per developer
Manoxy ry Iokyayur samoap fydeox zguronp o dpordep gnip uz rayaxb gugxebir ukuivhp ciktoq HZn baq qaheqacuk

Ticket to Merge detail screen showing a line chart comparing average days from ticket to merge for heavy and light AI users
Zabcey wu Camle zugais lpfoub jqisoxg o neje mqaql potdocikd abipudu kazt snoj rilwer lu pihho xim jiucj ugl wirzk AU iwenh

Correctness

First, you’ll look at a correctness issue in Models/DashboardStartDate.swift. You’ll cover one fix: Replacing an unsafe force unwrap with a safe fallback and an explicit calendar.

enum DashboardStartDate {
  static let today: Date = {
    // 1
    let calendar = Calendar(identifier: .gregorian)
    let components = DateComponents(
      year: 2026,
      month: 5,
      day: 1)
    // 2
    return calendar.date(from: components)
      ?? Date(timeIntervalSince1970: 1_777_593_600)
  }()
}
Tokens Dashboard Summary screen with the date line reading May 1, 2026
Buyegk Reydxaops Fajqorw zsleir tuzs twi neye tuha roatuzx Voq 3, 8819

Architecture

Next, you’ll look at an architecture issue split across TicketToMergeViewModel.swift and SummaryViewModel.swift. You’ll cover one fix: Having SummaryViewModel reuse the statistic TicketToMergeViewModel, instead of calculating it a second time.

init(
  costStore: ModelCostStore = ModelCostStore(),
  outcomeStore:
    DeveloperOutcomeStore = DeveloperOutcomeStore(),
  ticketToMergeViewModel:
    TicketToMergeViewModel = TicketToMergeViewModel()) {
// 1
let gapLine = """
  , now \(TicketToMergeViewModel.days(
      ticketToMergeViewModel.latestGapDays)
  ) days ahead of light AI users
"""
built.append(Insight(
// 2
  headline: """
    Heavy AI users now merge in \(TicketToMergeViewModel.days(
      ticketToMergeViewModel.latestAIHeavyDays)) days — \(
        KPIFormat.percent(ticketToMergeViewModel.heavyAIImprovement)) faster.
  """,
  detail: """
    Ticket to merge days for heavy AI users has been improving\(gapLine).
    AI-assisted development is clearly accelerating delivery from ticket to merge.
  """,
  destination: .ticketToMerge))
Ticket to Merge detail screen showing a line chart comparing average days from ticket to merge for heavy and light AI users
Pawdoz yo Rokhu femooy crziad tyuqafz i curi dmusm lugxiqixm uzogiwa hefz ncum yiczub sa xefxi doq xoizk ubr huqfr AI ecewb

Maintainability

You’ll now look at two maintainability issues: Inconsistent file naming, and colors that live outside the app’s shared design system. You’ll cover two fixes: Renaming three files so their casing is consistent, and centralizing two hardcoded colors.

Cost by Model detail screen showing a donut chart and ranked list of spend by AI model
Cifj yy Makix fogeeh djmaok zcemayz a cicej ymams ihh zihxam qopv et ftucg hb EA lecov

static let attentionAccent = Color.orange
.chartForegroundStyleScale(
  domain: ticketToMergeViewModel.cohortNames,
  range: [Color.indigo, ColorStyles.attentionAccent])
.foregroundStyle(
  point.needsCoaching ?
  ColorStyles.attentionAccent :
  Color.indigo)
Tokens vs Outcomes detail screen showing a scatter plot of tokens consumed against merged PRs per developer
Zedigy sq Aogjeson mineow hwjiiy ljeguwq a ddenbop qziv ix xedayg cefsowut ajuuxsg xetrab WNj baq ketutoqak

Ticket to Merge detail screen showing a line chart comparing average days from ticket to merge for heavy and light AI users
Fethes fe Burya legoej zjgoez ldafevt e muko sjusb mitqahapz ebojucu cubd xwel nelwij we hodse tuf baanh iwx labvy OI evavv

Performance and Security

Not every category turns up an issue, and it’s worth saying so plainly rather than manufacturing something to fill space. On a careful pass:

Accessibility

A quick pass here is genuinely encouraging. SummaryView groups each insight card into a single accessibility element with a clear combined label; CostByModelView‘s donut chart has a full descriptive label rather than just a chart. On a first read, this looks like solid work, so you won’t flag anything here now. However, it’ll be worth revisiting this section, when you’ll bring AI into the review process in the next lesson. A more exhaustive AI pass can sometimes catch things a quick human read doesn’t.

Testing

There isn’t a test target in this starter project yet. That’s a real gap, but it’s deliberately not something this lesson fixes: Writing and generating tests for code produced by AI is its own skill, and it’s covered in a different module. Noting a gap you don’t plan to address right now is still a legitimate part of a review; it just means writing it down instead of leaving it silently unmentioned.

See forum comments
Download course materials from Github
Previous: Introduction Next: Conclusion