Skip to content

Metrics for an AI-native SDLC

Metrics for an AI-native SDLC pair one leading indicator per lifecycle stage, which moves within days of a process change, with one lagging quality or reliability outcome that must not get worse. Both come from data a team already has: the git history of intent.md, spec.md and plan.md, pull request metadata, CI runs, deploys and the incident tracker.

Your team adopted the artifact chain two months ago. Pull requests merge faster, the tech lead says review feels heavier, and nobody can say which stage is slow or whether quality is holding. The DORA dashboard moves once a quarter, which is far too late to tell you that specs are being rewritten halfway through the build.

This page is for the developer who runs the AI-native lifecycle on a repository and the tech lead who reports on one team. It covers the per-stage signals. The organization-level definitions they feed, such as accepted change rate and cost per accepted change, live on one canonical page: DORA, SPACE, DX Core 4 and AI measurement.

What you get from per-stage lifecycle metrics

Section titled “What you get from per-stage lifecycle metrics”
  • A table with one leading and one lagging indicator for each stage and play, and where each number lives.
  • Four repository conventions that make every stage metric computable with git log and your code host’s API.
  • A decision table that turns a week’s numbers into one action.
  • Three copy-paste prompts: one writes the extraction script, one diagnoses a week of data, and one measures whether your instruction file is working.
  • A way to prove the numbers are right, and the failure modes that make them lie.

How do leading and lagging indicators work together?

Section titled “How do leading and lagging indicators work together?”

A leading indicator moves within hours or days of a change to one play: commit plan.md before implementing, and time from plan to merged pull request shifts the same week. A lagging indicator is the quality or reliability outcome that takes weeks to show: rework, escaped defects, change fail rate.

Read them as a pair, never alone. A play works when its leading indicator improves and its lagging indicator holds or improves. The evidence for pairing is DORA’s 2025 report (Google Cloud, 2025-09-23), which found “a positive relationship between AI adoption on both software delivery throughput and product performance”, and in the next sentence: “AI adoption does continue to have a negative relationship with software delivery stability.” A panel that shows only speed reports half of that finding.

Leading indicatorLagging indicatorWhat it meansWhat to do this week
ImprovesHolds or improvesThe play worksKeep it; instrument the next stage
ImprovesGets worseYou automated past the gate instead of through itStop expanding agent scope at this stage; tighten the gate’s evidence check
FlatHoldsThe play is not in use, or the data does not see itCheck marker coverage (see the verification section) before you blame the team
Gets worseImprovesThe gate is strict but slowAutomate the evidence check so a human reads findings, not the artifact

Which indicator belongs to each lifecycle stage?

Section titled “Which indicator belongs to each lifecycle stage?”

Each row is one play from the lifecycle. The source column names the system that already holds the timestamps, so none of these needs a new analytics product.

Stage and playLeading indicatorLagging indicatorWhere the data lives
Plan: capture intent.mdTime from the first request to a committed intent.mdShare of intents accepted into design versus closed; edits to intent.md after the first spec.md commitGit history of the intent folder
Design: write spec.mdTime from the intent.md commit to the accepted spec.md commitspec.md commits dated after the first plan.md commit for the same change (requirements rework)Git log
Build: plan mode, then implementShare of changes that merge from the first implementation pass; time from plan acceptance to merged pull requestRework cycles per change; how often the merged diff still matches the file list in plan.mdPull request metadata, drift-review findings
Build: instruction file (CLAUDE.md, AGENTS.md, Cursor Rules)Review comments that repeat a mistake the file should preventTime to first merged pull request for a new teammateReview comments; git history of the instruction file
Build: skillsTime from a policy owner’s approval to the updated skill mergingReview findings that cite that policy, which should fall toward zeroPull requests on the skills folder
Build: parallel sessionsSessions started per engineer per day (a team average, never broken out by person), and peak concurrent sessions, while first-pass merge share holdsMerged changes per repository per week, read beside rework cyclesAgent telemetry; pull request history
Test: session feedback loopFirst-pass CI success rate for agent-assisted changesTime in review per pull request; change fail rateCI runs; pull request metadata
Test: continuous evalsEval pass rate after each configuration change; time for an incident to become an evalRegressions caught in CI versus in productionEval suite results; incident tracker
Deploy: agent reviewTime to first review; share of review threads the authoring agent closed without a human commitDefects and vulnerabilities caught before merge versus in productionCode host; incident tracker
Deploy: approval-gate hooksTime each change waits at each gateGate violations that reach production, before versus after the hooksHook logs; incident tracker
Deploy: CI/CDShare of pipeline failures triaged without paging a humanDORA’s delivery metrics, per serviceCI and deploy tooling
Maintain: close the loopTime from a control-band breach to an intent.md in triageShare of findings that become merged fixes; repeat incidents of the same classDetection script log; pull request history
Maintain: scheduled scansShare of repositories on a schedule; time from finding to a fix in reviewVulnerabilities found by the scan versus in production or by outside reportScan history; incident tracker

The last Deploy row deliberately defers to DORA. Its five delivery metrics (change lead time, deployment frequency, failed deployment recovery time, change fail rate and deployment rework rate) are defined on the metrics frameworks page, and this page does not redefine them.

Make lifecycle metrics computable from git

Section titled “Make lifecycle metrics computable from git”

Most stage metrics are the time between two commits, or a count of commits after a date. They are computable only if the artifacts are committed at the moment they are accepted, in a predictable place.

  1. Give every change one folder. Keep intent.md, spec.md and plan.md for a change together, for example intent/notifications-digest/. The artifact chain’s note on where to put the files covers monorepos and multi-repository intent.

  2. Commit each artifact when it is accepted, not at the end. The timestamp of the commit that adds the file is the stage’s clock. A spec.md committed together with the implementation makes the design lead time zero and the metric meaningless. Squash merging does the same after the fact: it folds the intent.md, spec.md, plan.md and code commits of a branch into one commit on main, and git log on main cannot recover the separate timestamps. If you squash merge, either merge each accepted artifact in its own small pull request, use merge commits or rebase merging for change branches, or read the per-commit timestamps from the pull request’s commit list through the code host API (on GitHub, GET /repos/{owner}/{repo}/pulls/{pull_number}/commits) instead of from main.

  3. Put the change ID in the pull request. A Change: notifications-digest line in the pull request description joins code host data to the artifact folder. A CI check that fails when the line is missing keeps the join from rotting.

  4. Mark agent-assisted changes and follow-ups. Label agent-assisted pull requests (agent-assisted, or Claude Code’s own claude-code-assisted label where it is enabled). Reverts use git revert, whose message names the reverted commit. Fix-forward commits carry a Follow-up: #PR trailer that names the pull request they repair.

With those conventions in place, the git side of the table is three commands, all run in a terminal at the repository root:

Terminal window
# When each artifact was first committed: the stage clock for every change
# (%cI is the committer date, the same clock that --since reads)
git log --diff-filter=A --reverse --format='%h %cI' --name-only -- \
'intent/*/intent.md' 'intent/*/spec.md' 'intent/*/plan.md'
# Requirements rework for one change: spec.md commits after the first plan.md commit
CHANGE=notifications-digest
FIRST_PLAN=$(git log --diff-filter=A --format=%H -- "intent/$CHANGE/plan.md" | tail -1)
git log --oneline "$FIRST_PLAN"..HEAD -- "intent/$CHANGE/spec.md"
# Reverts and fix-forwards in the last 30 days
git log --since=30.days --grep='^This reverts commit' --format='%h %cI %s'
git log --since=30.days --format='%h %(trailers:key=Follow-up,valueonly,separator=%x2C)' | awk 'NF>1'

All three commands read committer dates, so a rebase moves a commit’s clock to the moment it was rewritten; read the numbers from the history you merge, not from a branch that is still being rebased. The rework command counts only spec.md commits that come after the first plan.md commit in history: a spec.md edit made in the same commit that adds plan.md is not rework, and the range $FIRST_PLAN..HEAD leaves it out.

Pull request, CI and deploy data come from your code host’s API. Rather than hand-writing that part, let an agent write the whole extraction as one script, with the prompt below, and commit it.

Every stage metric above comes from git, the code host, CI and the incident tracker, so it is identical whichever agent wrote the code. Only two rows depend on the tool: parallel sessions, and the agent-assisted marker. Full instrumentation, including cost, is on the metrics frameworks page.

Claude Code exports OpenTelemetry metrics and events when telemetry is on. Set it for the team through managed settings. claude_code.session.count counts sessions started, not sessions running at once: count sessions started per engineer per day from it, and derive concurrency from overlapping session.id activity in the exported events:

{
"env": {
"CLAUDE_CODE_ENABLE_TELEMETRY": "1",
"OTEL_METRICS_EXPORTER": "otlp",
"OTEL_LOGS_EXPORTER": "otlp",
"OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
"OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317"
}
}

On Team and Enterprise plans with the Claude GitHub app installed and GitHub analytics turned on, merged pull requests with Claude Code-assisted lines get the claude-code-assisted label. Contribution metrics are in public beta and are not available with Zero Data Retention; use your own agent-assisted label there (checked against the Claude Code analytics docs on 2026-09-26). An Owner turns on the GitHub analytics toggle in Claude Code admin settings.

For a collector and dashboards, see agent observability; ccusage (npx ccusage@latest) gives per-machine session and cost counts without a server.

Start where the data already exists and the leverage is highest, then move upstream. Before you change any play, reconstruct at least three months of history for its indicators, so the first week after the change has something to be compared with.

  1. Test and Deploy first. First-pass CI success, time to first review and time in review need no new convention: your CI and code host already hold them. They also show the most common bottleneck once agents write code, which is review.

  2. Build next. Add the change ID line and the agent label, and start committing plan.md. First-pass merge share and rework cycles become computable.

  3. Design and Plan after that. Once intent.md and spec.md are committed at acceptance, the design lead time and requirements rework rows fill in.

  4. Maintain last. The close-the-loop rows need a deterministic detection script and a triage queue first; the Maintain stage sets those up.

  5. Review weekly in the retrospective. The tech lead brings the decision table and one week of data, and the team picks one stage to change. The prompt below does the first read.

How do you know the lifecycle metrics are right?

Section titled “How do you know the lifecycle metrics are right?”

A metric that nobody checks becomes the least-reviewed artifact in the repository. Four checks keep these honest without anyone re-reading the data by hand every week.

  • No model computes a number. The extraction script is deterministic, committed and unit-tested against a fixture repository, the same rule the control-band detection follows. Agents write the script and interpret its output; they never produce the numbers.
  • Report marker coverage beside every metric. If only half the merged pull requests carry a change ID, a design lead time computed from them describes half the team. Treat a row with coverage below 80% as a warning, not a result.
  • Spot-check ten changes a month. Pick ten merged pull requests at random and compare the script’s timestamps, labels and follow-up links with the history by hand. More than one disagreement in ten means the extraction logic is wrong, not the team.
  • Keep the pair rule and the unit. Every leading indicator appears on the same view as its lagging one, and every number is per repository or service (team averages are fine), never a view of one engineer.

The tech lead owns the team’s weekly view and signs off each change to a play. The definitions themselves belong to the organization’s metrics owner named on the metrics frameworks page; a team does not change a formula locally.

What goes wrong with lifecycle metrics, and how to recover

Section titled “What goes wrong with lifecycle metrics, and how to recover”

A leading indicator becomes a target. Someone sets “specs within one day”, and specs get thinner. Requirements rework then rises in the Build stage. Recovery: remove the target, show design lead time only beside requirements rework, and discuss the pair in the retrospective.

Artifacts are committed in bulk. intent.md, spec.md and plan.md land in the same commit as the code, so every stage lead time reads zero. Recovery: add a CI check that fails a pull request when its change folder has no plan.md in an earlier commit, and reconstruct history only from changes that pass it.

Squash merge erases the stage clock. Each artifact was committed on time on the branch, but the squash put them all into one commit on main, so every stage lead time reads zero again and git log on main cannot tell. Recovery: merge each accepted artifact in its own small pull request, switch change branches to merge commits or rebase merging, or have the extraction script read per-commit timestamps from each pull request’s commit list through the code host API rather than from main.

Rework hides as new work. A fix for last week’s agent change arrives as a new feature pull request with no link, so first-pass merge share looks perfect. Recovery: make the Follow-up: #PR trailer part of the review checklist, and have the review agent flag fixes to recently merged code that lack it.

Parallel sessions rise and rework rises with them. Throughput looks better while each change needs more rounds. Recovery: cap concurrent sessions per engineer at the last level where first-pass merge share held, and raise it again only when the Test stage’s first-pass CI success improves.

Review load moves to a few seniors. Time in review grows, but only for pull requests that need two particular reviewers. Recovery: split time in review by reviewer group (not by person), set pull request size budgets, and see how to keep the review queue moving.

Numbers turn into a leaderboard. Per-engineer views appear, and the team starts optimizing the counts. Recovery: delete the per-person views, state in the team’s working agreement that these metrics describe the process, and keep individual performance out of them.

Start from the lifecycle overview if the stages are new to you. When the per-stage signals are in place, roll them up with the organization-level definitions.