Blog

git blame for AI agents

When an agent writes the line, the author column goes blank. cast blame fills it back in — with the conversation that wrote it.

the codecast team6 min read

The author column is going blank

Open a file your team shipped last month and run git blame. Every line carries an author, a date, a commit message. Now ask the author why line 8 imports what it imports. More and more often, there is nobody to ask. An agent wrote it, in a terminal session that closed hours ago, and everything it knew while writing — the files it read, the approach it rejected, the reason it landed here — closed with the process.

Agents already write a large share of the code that ships. In a controlled study of a large enterprise rollout, engineers given command-line agents merged 24% more pull requests per day, rising to 50% for the ones who used them five or more days a week (Microsoft, 2026). The commit still lands under a human name, because a human ran git commit. But git blame answers what changed and when. The why — the part you actually need during review — lived in the conversation, and the conversation is gone.

The gap this leaves

This would be a footnote if reviewing agent code were easy. It is not; it is the bottleneck. Simon Willison, who moved to running agents in parallel through 2025, puts it plainly: the binding constraint is review capacity, not how fast the agents produce code.

And developers do not extend the benefit of the doubt. In Stack Overflow's 2025 developer survey, 46% said they distrust the accuracy of AI output, and 66% named “almost right” code as their single biggest frustration. DORA's 2025 report found roughly 30% still place little or no trust in AI-generated code. “Almost right” is the worst kind of line to inherit: it passes a glance and fails under load, and the one who could explain it is a stateless process that already exited. So you re-derive the intent by hand — slower than if you had written the line yourself.

What cast blame does

git blame answers who wrote this. For agent-written code the useful answer is not a person; it is the conversation. cast blame is git blame with that column swapped: the author of each line is the codecast session that produced it. Nothing about your workflow changes — you still run agents in a terminal, still commit under your own name. The daemon watches the sessions as they happen and keeps the mapping from line to conversation, so the attribution is there when you go looking for it.

cast blame
$ cast blame -L 1,9 packages/convex/convex/notifications.ts
1cc1592e3 (jx75w7g Ashot Cross-device session sync          2026-06-14 19:59:09 -0400 1) import { mutation, query, internalAction, internalMutation } from "./functions";
a15290d7d (Ashot Petrosian                                  2025-12-24 13:16:30 -0800 2) import { v } from "convex/values";
a15290d7d (Ashot Petrosian                                  2025-12-24 13:16:30 -0800 3) import { internal } from "./_generated/api";
e5657b8e6 (Ashot Petrosian                                  2025-12-24 16:08:21 -0800 4) import { getAuthUserId } from "@convex-dev/auth/server";
726e57342 (jx708f9 Ashot Topical Commits and Conflict Res.. 2026-02-07 23:32:38 -0800 5) import { verifyApiToken } from "./apiTokens";
69add29d7 (jx72v1e Ashot Deploy forced CLI release          2026-04-07 13:47:42 -0500 6) import { isConversationTeamVisible } from "./privacy";
beda6c5e2 (jx710sn Ashot Worktree consolidation             2026-07-08 20:01:09 +0300 7) import { isAgentSpawnedConversation } from "./ccAccountsShared";
c1707b627 (jx76xy4 Ashot Codecast ownership model refactor  2026-07-14 14:42:08 +0400 8) import { listSessionOwnerIds } from "./sessionOwners";
9ed63bb00 (Ashot Petrosian                                  2026-07-13 15:36:26 +0400 9) import {

Read the author column. The leading token — jx76xy4, jx710sn, jx75w7g — is a codecast session, and the text beside it is that session's title: Codecast ownership model refactor, Worktree consolidation, Cross-device session sync. Lines marked only Ashot Petrosian predate the record or came from an ordinary hand edit; cast blame does not invent an author it does not have. In this file, 382 of 843 lines trace back to a specific session.

Step back from lines to sessions and you get the shape of the file's history:

cast blame --log
$ cast blame --log packages/convex/convex/notifications.ts
Sessions that shaped ~/src/codecast/packages/convex/convex/notifications.ts  (382/843 lines attributed)

  jx7bn26  Ashot   773469c14  Daemon flush cadence fix                     3 lines  2026-07-20
  jx74vrz  Ashot   a28115d2b  Notification aggregation per conversat..    29 lines  2025-12-24→2026-07-20
  jx76xy4  Ashot   c1707b627  Codecast ownership model refactor           70 lines  2026-07-14
  jx70at5  Ashot   9ed63bb00  Idle session notifications                  46 lines  2025-12-25→2026-07-13
  jx73xhc  Ashot   9ed63bb00  Team session notifications gate fix          7 lines  2025-12-25→2026-07-13
  jx707cd  Ashot   9ed63bb00  Notification settings granular control       3 lines  2025-12-25→2026-07-13
  jx78db2  Ashot   9ed63bb00  Notification system audit & implementa..     3 lines  2025-12-25→2026-07-13
  jx779qm  Ashot   9ed63bb00  Fork: Agent Queue UI Implementation          3 lines  2026-02-17→2026-07-13
  …  17 more sessions

Each row is a conversation that shaped this file, newest first, with how many of its lines survive and the span of dates it touched. It is the map of where the file came from, rebuilt from agent work that would otherwise have evaporated at the end of each session.

From a line to the conversation

The point is not the label. The point is that the label is a link. cast blame is a drop-in replacement for git blame — the default and porcelain formats match byte for byte, so anything that already shells out to git blame can call cast blame instead. Alongside git's own fields, porcelain adds six codecast-* keys — session, conversation, title, author, url, and message:

cast blame --porcelain
$ cast blame packages/convex/convex/notifications.ts:8 --porcelain
c1707b627059816451a7c1967ffce25b9e55d871 8 8 1
…  author + committer block (name, email, timestamps) trimmed  …
summary feat(sessions): owners as an independent set — multi-owner handoff with notification
codecast-session jx76xy4
codecast-conversation jx76xy4kp0dngmd2vzbn3sjvqd8ahvsr
codecast-title Codecast ownership model refactor
codecast-author Ashot Petrosian
codecast-url https://codecast.sh/conversation/jx76xy4kp0dngmd2vzbn3sjvqd8ahvsr
codecast-message k171az4qwtbck5fnc3rmbvpy1s8agha1
…  git trailers (previous, filename, content) trimmed  …

Take line 8. Blame says it came from jx76xy4, Codecast ownership model refactor. Open that session and you see why listSessionOwnerIds is imported here at all: the refactor made ownership an independent set, so notifications had to resolve a list of owners instead of a single author. That reason is one click from the line — not guessed from a commit summary, but the actual conversation, prompt and dead ends included.

That codecast-url is the conversation link, and codecast-message pins the exact turn; cast blame src/file.ts:8 --open just opens it for you. In your editor it is closer still: the VS Code and Cursor extension shows the session that wrote the current line at the end of the line, the way GitLens shows the commit, and lets you open the conversation behind it. For vim, cast blame --install-fugitive points fugitive at a shim so :Gblame renders sessions in the author column.

Blame is one query over the record

Line attribution is one view of a larger thing: every agent conversation your team has run, kept and searchable instead of discarded when the terminal closes. cast search "auth" greps it like ripgrep; cast ask "how did we implement auth?" answers from it. It spans agents and machines — Claude Code, Codex, Cursor, Gemini — not one vendor's cloud runs, because the daemon watches the local sessions you already run, wherever you run them.

This is where it stops being a personal convenience. The person who ran git commit may have skimmed the diff and approved it; six weeks later the teammate who has to change that code is a different person again. With the record, the author to ask is attached to the line for both of them. The reasoning outlives the session, the reviewer, and the terminal that produced it.

That is the whole idea, and it is why the author column does not have to stay blank.

Codecast is where your team sees, steers, and remembers every coding agent session — any agent, any machine.

Sources: Stack Overflow 2025 Developer Survey; DORA 2025 State of AI-assisted Software Development; a controlled study of a large enterprise command-line agent rollout (Microsoft, 2026); Simon Willison on parallel agents. Terminal output is genuine cast blame from this repository, captured 2026-07-20 — the line blame is verbatim; the --log and --porcelain views are excerpts with every omission marked (the porcelain author/committer block and git trailers are trimmed).