---
title: "DevExOps"
slug: devexops
category: delivery
term_status: ambiguous
evidence_status: verified
summary: "DevExOps is a rare, unstandardised label. This page uses it for running developer experience as a continuous loop: measure friction with surveys and system data, prioritise it, get it fixed and verify the fix, without turning the data into surveillance of individuals."
audience: [Engineering managers, DevEx and platform teams, Staff engineers, Engineering leaders, Beginners]
last_verified: 2026-10-17
key_takeaways:
  - "DevExOps is not an established term: searches on 2026-10-16 found no published definition. The field behind it, developer experience (DevEx), is well researched. Reading the \"Ops\" as a continuous measure-and-improve loop is this Atlas's editorial choice."
  - "The DevEx framework (Noda, Storey, Forsgren, Greiler, 2023) has three dimensions: feedback loops, cognitive load and flow state. Its authors warn that DevEx is not mainly about tools; clear goals and psychological safety matter too."
  - "Use two instruments that check each other: stable surveys for perceptions and system data for workflows. When they disagree, investigate before you act."
  - "Measure only when someone with authority will act on either result, and report back every cycle. Surveys that lead nowhere teach people to stop answering."
  - "Report teams and personas, never individuals. Activity metrics used in performance reviews get gamed, and some jurisdictions give works councils or regulators a say over monitoring tools."
  - "DevExOps diagnoses and verifies; PlatformOps and product teams ship most fixes. A finding closes only when the next measurement moves beyond a threshold agreed before the fix, which small teams rarely reach in one cycle."
  - "In a 2025 randomised trial with early-2025 AI tools, experienced developers estimated that AI had cut their task time by 20% when it actually took 19% longer. Evaluate such changes with system data and experiments, not sentiment alone."
related: [platformops, devops, testops, peopleops, sre, productops, agileops, gitlabops]
---

## What DevExOps is

### In 30 seconds

**DevExOps** is not a recognised discipline. It is a rarely used compound of **DevEx** (developer experience) and **Ops**. The
research field behind it is real: developer experience "encompasses how developers feel about, think about, and value their
work", and the 2023 DevEx framework reduces it to three dimensions: "feedback loops, cognitive load, and flow state".[^devex]

This page uses the label for **running developer experience as an operation**: find where engineers lose time and attention
(slow builds, CI queues, review waits, confusing tools, interruptions), measure it with surveys and system data, get it fixed by
its owner, and verify that the next measurement moved beyond the noise. That reading is an **editorial choice of this Atlas**
([below](#what-it-is-not-the-label-boundaries-and-misconceptions)): a measure-prioritise-verify loop run with the discipline of an
operations team and the ethics of a research team.

**For** leaders who want insight without surveillance, DevEx and platform teams, staff engineers and beginners.
**Last verified:** 2026-10-17.

### At a glance

| | |
|---|---|
| Goal | Less friction in engineering work, shown by measurement, not anecdote |
| Users | Anyone who ships code |
| In scope | DevEx dimensions, SPACE, inner and outer loop, build, CI and review waits, onboarding, development environments, surveys plus system data, responsible measurement |
| Out of scope (linked) | Building the fixes → [PlatformOps](../platformops/); delivery metrics and CI/CD → [DevOps](../devops/); test-signal reliability → [TestOps](../testops/); individual performance → [PeopleOps](../peopleops/); team work-item flow → [AgileOps](../agileops/) |
| Prerequisites | [DevOps](../devops/) basics; comfort with medians and percentiles |
| Key outputs | A stable survey; a metric catalogue; quarterly readouts per team and persona; an owned findings backlog; verified fixes |
| Term status | **Ambiguous**: a rare coinage with no published definition; teams doing this work are called developer experience, developer productivity, engineering effectiveness or engineering enablement[^leaddev-team] |

### The problem it solves

Most organisations sense friction; few can say **which**, **for whom**, **how much**, and **whether the fix worked**:

| Without a DevEx loop | With one |
|---|---|
| The loudest complaint gets funded; small groups stay invisible | Results by team and persona reveal what averages hide[^devex] |
| Commits or pull requests are counted as productivity | Several dimensions in tension, at least one perceptual[^space] |
| A survey runs once, nothing changes, response rates fall | Every survey ends with owned findings[^devex] |
| "We made CI faster" is asserted | The same measures compared before and after |

The value is decision quality, at a price: the improvement cycle "also takes human resources", and spending 50 engineers a year
to gain the equivalent of 10 is not worthwhile.[^swe-ch7]

### What it is not: the label, boundaries and misconceptions

**The label.** Searches on 2026-10-16 (two search engines, GitHub) found **no published definition** of "DevExOps", only an
inactive GitHub account and a domain for sale. Nearby labels:

| Label | What it means | Source |
|---|---|---|
| DevEx, DX, DevX | Developer experience, the research field this page draws on | Fagerholm and Münch;[^fagerholm] Noda et al.[^devex] |
| DevEx (Roblox) | Roblox's Developer Exchange programme, converting creators' earnings to currency | Roblox[^roblox] |
| DevXOps | An IT-services brand for "Development, Operations and User Experience throughout SDLC" | YASH[^yash] |
| Developer Productivity Engineering (DPE) | A label promoted by Gradle, whose DPE page now redirects to its Develocity product | Develocity[^dpe] |

This Atlas gives the term the reading that does not duplicate a neighbour: **DevExOps is the diagnose-and-verify loop;
[PlatformOps](../platformops/) builds and runs most fixes.** That split is an **editorial distinction**; often one team does both.

**Boundaries.** DevExOps is not:

- **A tools team.** The DevEx authors call it a misconception that DevEx is "primarily affected by tools"; human factors such as
  clear goals and psychological safety have "a substantial impact".[^devex]
- **Scoring people.** SPACE warns that activity metrics "should never be used in isolation either to reward or to penalize
  developers".[^space] Individual performance belongs to [PeopleOps](../peopleops/).
- **DORA under another name.** DORA's metrics ([DevOps](../devops/)) describe delivery outcomes; DevExOps studies the
  experience behind them.
- **Only a survey programme.** Developers can be content with needlessly slow builds, and fast reviews can still feel
  disruptive: each instrument misses what the other sees.[^devex]
- **Always needed** ([when not to use](#when-to-use-and-when-not-to-use)).

## Where it comes from and where it sits

### Origins and evolution

| When | Milestone |
|---|---|
| 2012 | Fagerholm and Münch, by analogy with user experience, propose defining developer experience as "a means for capturing how developers think and feel about their activities within their working environments".[^fagerholm] |
| March 2021 | SPACE: productivity "cannot be reduced to a single dimension (or metric!)".[^space] |
| 2022 | Greiler, Storey and Noda derive the "DX Framework" from interviews with 21 developers.[^greiler] |
| May 2023 | Noda, Storey, Forsgren and Greiler condense it to three dimensions.[^devex] |
| August 2023 | A McKinsey article proposes measures including individual "contribution analysis";[^mckinsey] Gergely Orosz and Kent Beck rebut it.[^orosz-beck] |
| December 2023 | LinkedIn open-sources its Developer Productivity and Happiness (DPH) framework.[^dph-blog][^dph] |
| January 2024 | "DevEx in Action" links the three dimensions to outcomes in a survey study.[^devex-action] |
| January 2025 | The vendor DX launches "DX Core 4", written with DevEx and SPACE co-authors.[^infoq-core4][^core4] |

**Conflict of interest.** Two of the four DevEx authors were at DX, which sells DevEx surveys, when the paper was published; a
third, Storey, listed a DX affiliation from 2024. "DevEx in Action" surveyed DX's customers, as its authors
state.[^devex][^devex-action] Treat its benchmarks and results as a vendor's.

### Glossary and mental model

**Mental model: friction is a queue in front of a person.** Every wait (build, runner, reviewer) and detour (unclear tool,
missing document) stands before the next step. DevExOps finds the longest queues, gets them shortened and checks that they shrank.

| Term | Meaning on this page | Example |
|---|---|---|
| Feedback loops | "the speed and quality of responses to actions performed", from tools and from people[^devex] | Build result, CI verdict, review comment |
| Cognitive load | "the amount of mental processing required for a developer to perform a task"[^devex] | Ten tools and three wikis to deploy one service |
| Flow state | Being "fully immersed in a feeling of energized focus, full involvement, and enjoyment"[^devex] | Two uninterrupted hours on a hard problem |
| SPACE | Satisfaction and well-being, performance, activity, communication and collaboration, efficiency and flow[^space] | Metrics from three or more dimensions |
| Perceptual / workflow measure | Self-reported experience / system data[^devex] | CI-speed satisfaction / P90 CI time |
| Inner loop | Work "before code is shared with the team or deployed to production": edit, build, test, debug[^ms-inner] | Re-running unit tests after an edit |
| Outer loop | Work after code is shared through a pull request: reviews, automated checks, merge, deploy[^ms-inner] (McKinsey's list differs slightly[^mckinsey]) | Waiting for a reviewer |
| P50 / P90 | Values that half / nine in ten of measurements fall below: the median and the slow tail | CI P90 of 34 minutes: one run in ten is slower |
| Favourable share | Share of a group's answers that are 4 or 5 on a 5-point scale | 18%: under one answer in five positive |
| Persona | Developers with a similar workflow, used to break down results[^dph-personas] | Mobile, backend Java, data engineering |
| Experience sampling | Interrupting people during a task to ask about it[^swe-ch7] | A pop-up after a slow build |
| Finding | Friction with evidence, an owner and a verification metric | "CI queue P90 is 22 minutes at 10:00 UTC" |

**Two meanings of cognitive load.** DevEx's is per developer and task; Team Topologies' *team* cognitive load spans a team's
tools, responsibilities and domains,[^tt-concepts] the sense [PlatformOps](../platformops/) uses.

### How DevExOps relates to other Ops

DevOps, TestOps and AgileOps supply data and context; PlatformOps and product teams receive findings; PeopleOps receives **no
individual data**.

| Neighbour | Shared scope | This page's focus | Choose the neighbour when |
|---|---|---|---|
| [PlatformOps](../platformops/) | Reducing cognitive load, golden paths | Which friction matters; verifying fixes (**editorial distinction**) | You know the fix and need to build or run it |
| [DevOps](../devops/) | Feedback, flow, DORA metrics | The experience behind the delivery numbers | You need CI/CD or DORA definitions |
| [TestOps](../testops/) | Waiting for CI | Test duration and flakiness as one input | The suite is slow or untrustworthy |
| [PeopleOps](../peopleops/) | Surveys, people data | Systems and teams, never individuals | The question is about one person's performance |
| [SRE](../sre/) | Objectives for internal systems | Which developer-facing systems deserve one | You are designing the SLO |
| [AgileOps](../agileops/) | Flow and interruptions | Tool and process friction | The friction is planning cadence or WIP |
| [ProductOps](../productops/) | Feedback loops with users | Developers as the users | Your users are external |
| [GitLabOps](../gitlabops/) | CI runners and pipelines | Tool-neutral measurement | You need GitLab-specific features |

## Principles and operating model

### A proposed charter and principles

No DevExOps charter has been published; this is **this Atlas's proposal**. **Mission:** find the friction that costs developers
most, get it removed by its owner, prove the removal, and never let the data harm those who gave it.

| Principle | What it means in practice | Grounding |
|---|---|---|
| Decision first | Name the decision and decider before collecting anything | Google: measure "only" when "a concrete decision will be made based on the outcome"[^swe-ch7] |
| Two instruments | Pair a perceptual and a system measure per signal | DevEx: "neither alone can tell the full picture"[^devex] |
| Disagreement is a finding | When survey and logs diverge, investigate before acting | Google: the quantitative metric was usually at fault[^swe-ch7] |
| Teams and personas, never individuals | Aggregate; suppress small groups | SPACE: "report only anonymized, aggregate results at the team or group level"[^space] |
| Stable instruments | Version questions; change them rarely | CNCF: changing questions between runs negates "the ability to track progress"[^cncf-pemm] |
| Close the loop in public | Every cycle ends with a readout and owners | No follow-up, survey fatigue[^devex] |
| Verify, don't assert | A finding closes when the next measurement moves beyond a threshold set in advance ([rule](#when-has-a-measure-moved)) | This Atlas's rule |
| Proportion | The loop must cost less than the friction it removes | Google's 10-versus-50-engineers test[^swe-ch7] |

**Non-goals:** ranking teams or individuals; benchmark targets.

### Building blocks: three dimensions, two loops, two instruments

Dimensions say *what* to look at, loops *where* friction sits, instruments *how* to see it.

| Dimension | Typical friction | Perceptual example | System example | Usual fix owner |
|---|---|---|---|---|
| Feedback loops | Slow builds, CI queues, slow reviews, slow answers | Satisfaction with CI speed | P90 CI feedback time; review response time | Platform team; reviewers |
| Cognitive load | Unclear tools, missing documentation, hard code | "I can find what I need without asking" | Joiners' time to first merged change; help requests per persona | Tool and documentation owners |
| Flow state | Interruptions, meetings, unplanned work | Satisfaction with deep-work time; how often unplanned work intrudes | Unplanned work reaching a team per engineer-week | Managers and leaders |

The evidence is uneven. "DevEx in Action" (219 respondents at DX customers, one point in time) linked flow state and cognitive load
to developer, team and organisation outcomes, but feedback loops, measured only as review time and quick answers, to team outcomes
alone. Its figures are self-reports: use them to choose hypotheses, not to promise returns.[^devex-action]

::: figure Inner loop and outer loop, with the waits DevExOps measures
```mermaid
---
config:
  flowchart:
    wrappingWidth: 130
    nodeSpacing: 30
---
flowchart TB
  E["Edit code"] --> B["Local build: wait"]
  B --> T["Local tests: wait"]
  T -->|"fails"| E
  T -->|"passes"| P["Push and open pull request"]
  P --> Q["CI queue: wait for a runner"]
  Q --> C["CI run: wait for verdict"]
  C -->|"red"| E
  C -->|"green"| R["Review: wait for a reviewer"]
  R -->|"changes asked"| E
  R -->|"approved"| M["Merge and deploy"]
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class E,P,M core
  class B,T,Q,C,R risk
```
Text equivalent: The inner loop runs from editing through a local build and tests; failures return to editing. Passing tests lead
to the outer loop: pull request, CI queue, CI verdict, reviewer. A red run or changes asked by the reviewer return to editing;
approval leads to merge and deploy. The five waits are drawn in the risk colour.
:::

Inner-loop time should be "proportional to the size of changes made" (Microsoft): a one-line change that triggers a ten-minute
rebuild is a finding.[^ms-inner] The loops also pull against each other: Google sets "One business day" as the maximum time to
respond to a review, yet tells reviewers in a focused task not to interrupt themselves.[^google-review] Measure both.

### Roles, ownership and RACI

The **DevEx team** has a lead (in effect its product manager), a researcher or analyst and a data engineer (collection and the
privacy gate). [PlatformOps](../platformops/) ships most cross-cutting fixes; managers own local friction such
as meetings; **persona champions** speak for a persona, a role LinkedIn's framework describes;[^dph] privacy, legal and any
works council approve the data-use policy; a sponsor funds fixes. RACI: R = responsible, A = accountable, C = consulted, I = informed.

| Activity | DevEx team | Platform team | Managers | Privacy/legal | Sponsor |
|---|---|---|---|---|---|
| Survey design and change control | A/R | C | C | C | I |
| Data-use policy | R | C | C | A | I |
| Collection pipeline and privacy gate | A/R | C | I | C | I |
| Quarterly readout | A/R | C | R (team sessions) | I | I |
| Prioritising cross-team findings | R | C | C | I | A |
| Shipping platform fixes | C | A/R | I | I | I |
| Local team fixes | C | I | A/R | I | I |
| Verifying a fix | A/R | C | I | I | I |

### Lifecycle: the measure-and-improve loop

::: figure The DevExOps loop: one cycle per quarter
```mermaid
---
config:
  flowchart:
    wrappingWidth: 130
    nodeSpacing: 30
---
flowchart TB
  Q["1. Decide the question and the decider"]
  I["2. Instrument: survey items and metrics"]
  C["3. Collect: survey window, telemetry"]
  A["4. Analyse by team and persona"]
  P["5. Prioritise findings with owners"]
  F["6. Owners fix: platform or team"]
  V["7. Verify with the same measures"]
  Q --> I --> C --> A --> P --> F --> V
  V -->|"moved: close"| Q
  V -.->|"noise: reopen"| P
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  class Q,I,C,A,F core
  class P,V decision
```
Text equivalent: A seven-step cycle: decide the question and decider; instrument; collect; analyse by team and persona;
prioritise findings with owners; owners fix; verify with the same measures. If the measure moved past the threshold agreed in
advance ("moved: close"), the finding closes and a new cycle starts; within noise ("noise: reopen", dotted arrow), it returns to
prioritisation. Prioritise and verify are decisions.
:::

- **Day 0 (4–6 weeks):** charter; data-use policy agreed with privacy and any works council; survey; two or three system metrics.
- **Day 1 (first cycle):** baselines, a readout to every team, three owned findings.
- **Day 2 (steady state):** a survey every three to six months, as both DevEx papers suggest;[^devex][^devex-action] monthly metric
  review with the platform team; findings triage every two weeks; a yearly instrument review.

### Operating model and governance

- **Change control.** Each survey item has an ID, wording, scale and version; changes "should usually remain small to allow for
  comparisons over time".[^devex-action]
- **Data-use policy.** Written before the first survey, banning performance-review use ([template](#templates)).
- **Escalation.** Findings no platform can fix go to the sponsor: DORA found unstable priorities cause "meaningful decreases in
  productivity and substantial increases in burnout".[^dora-2024]
- **Readout order.** Teams see results before leaders do.

## Architecture and workflow

### Reference architecture

::: figure Reference architecture: two instruments, one privacy gate, one comparison
```mermaid
---
config:
  flowchart:
    wrappingWidth: 150
    nodeSpacing: 15
---
flowchart TB
  subgraph PER["Perceptions"]
    S1["Survey"]
    S2["Prompts"]
  end
  subgraph SYS["System data"]
    S3["CI and VCS events"]
    S4["Build timings"]
  end
  ING["Ingest: drop names, map to team and persona"]
  GATE["Privacy gate: min group, no row export, retention"]
  FAV["Favourable shares by team and persona"]
  PCT["P50 and P90 waits by team and persona"]
  CMP["Compare: agreements and disagreements"]
  O1["Output: team readouts"]
  O2["Output: findings backlog"]
  O3["Output: leader KPIs"]
  S1 --> ING
  S2 --> ING
  S3 --> ING
  S4 --> ING
  ING --> GATE
  GATE --> FAV
  GATE --> PCT
  FAV --> CMP
  PCT --> CMP
  CMP --> O1
  CMP --> O2
  CMP --> O3
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class ING,FAV,PCT core
  class GATE risk
  class CMP decision
  class S1,S2,S3,S4,O1,O2,O3 neutral
```
Text equivalent: Perceptions (survey, prompts) and system data (CI and version-control events, build timings) enter an ingest
step that drops names and maps records to team and persona. A privacy gate (risk colour) enforces a minimum group size, no row
export and retention. Favourable shares and P50/P90 waits are computed side by side, then compared (decision colour) to feed team
readouts, the findings backlog and leader KPIs.
:::

| Component | Responsibility | Design choice and trade-off |
|---|---|---|
| Event collection | CI jobs, pull-request events, build timings | Select fields so names never land |
| Mapping tables | Repository → team; person → team and persona | The only place identity exists: restrict and audit |
| Privacy gate | Suppress small groups and figures they could be derived from; delete raw rows | Lower thresholds: finer detail, more re-identification risk |
| Analysis | Percentiles, favourable shares, trends, disagreements | P50 and P90 for experience (waits are skewed); means only for totals |
| Findings backlog | Evidence, owner, metric, target, verification date | In the normal work tracker, not a slide deck |

**Trust boundary:** raw answers and per-person rows stay inside the gate; only aggregates leave.

### End-to-end workflow: from friction signal to verified fix

::: figure From signal to verified fix, with the exception paths
```mermaid
---
config:
  flowchart:
    wrappingWidth: 130
    nodeSpacing: 30
---
flowchart TB
  S["Signal: survey, telemetry, complaint"]
  D{"Agree?"}
  X["Investigate: interviews, sampling"]
  M["Fix metric definition"]
  F["Finding: evidence, owner, target"]
  O{"Owner accepts?"}
  E["Sponsor decides"]
  FIX["Owner ships fix"]
  V{"Past threshold?"}
  CL["Close, publish result"]
  R["Reopen: investigate again"]
  S --> D
  D -->|"no"| X
  D -->|"yes"| F
  X -->|"metric wrong"| M
  M -.->|"compare again"| D
  X -->|"real, unmeasured"| F
  F --> O
  O -->|"yes"| FIX
  O -->|"no"| E
  E --> FIX
  FIX --> V
  V -->|"yes"| CL
  V -.->|"no"| R
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  class F,FIX,CL core
  class D,O,V decision
  class S,X,M,E neutral
  class R risk
```
Text equivalent: A signal arrives from a survey, telemetry or a complaint. If survey and system data agree, a finding is written.
If not, interviews or sampling follow: a wrong metric is redefined and compared again (dotted arrow back to "Agree?"); real but
unmeasured friction becomes a finding. The owner ships the fix, or the sponsor decides. Past the threshold, the finding closes and
the result is published; if not (dotted arrow), it is reopened and investigated again (risk colour).
:::

**A real exception path:** Google's build-latency metric first counted builds started by automated tools, which nobody waited
for.[^swe-ch7]

## Practices, frameworks and tools

### Core practices and playbooks

| Practice | Goal | Trigger | Owner | Output | Verification |
|---|---|---|---|---|---|
| Periodic survey | Trend per dimension, team, persona | Every 3–6 months | Researcher | Favourable shares | Same items as last cycle |
| Transactional prompt | Feedback at a precise moment[^devex] | Failed setup, slow build | Tool owner | One-question ratings | Rating trend |
| Experience sampling | Check a metric matches experience[^swe-ch7] | New or doubted metric | Researcher | Corrected definition | Survey and logs agree |
| Inner-loop stopwatch | Time build and test commands | Toolchain change | Platform team | P50, small versus full change | Repeatable benchmark |
| CI feedback tracking | P50 and P90, queue versus run | Monthly | Data engineer | Lab 2 report | Trend after each fix |
| Review nudges | Unblock stale pull requests | Idle past a threshold | Platform team | Reminder to the blocker | Resolution time (Nudge) |
| Onboarding audit | Catch setup friction while fresh | Each new joiner | Manager, buddy | Setup log | Cohort median falls |
| Persona interviews | Explain the numbers | Surprise or disagreement | Researcher | 5–8 interviews | Finding with evidence |

**Playbook: the first survey.** Acceptance: a readout with three owned findings within four weeks of closing.

1. Write the decision and the decider ([Lab 1](#hands-on-labs)); agree the data-use policy before collecting anything.
2. Draft 15–25 items across the dimensions plus outcome questions such as ease of delivery (the DevEx paper's KPIs). Reuse
   validated items; test new wording in interviews: poorly designed questions "lead to inaccurate and unreliable results".[^devex]
3. Fix personas and the minimum reporting group before launch.
4. Open for two weeks; publish response rates per team, never names of non-respondents.
5. Read out to teams first, then leadership, with owners and dates.
6. **Rollback:** if too few answer, publish only merged groups and rebuild trust before re-running.

_Example status: syntax-checked, not executed (needs a repository with `make` targets and hyperfine 2.0 or later)._

```bash
# Inner-loop stopwatch: a one-file change against the full suite, warm caches,
# 5 runs each. hyperfine 2.0.0 (2026-10-07) runs commands without a shell by
# default; -S restores shell parsing.
hyperfine -S --warmup 1 --runs 5 \
  --prepare 'touch src/payments/handlers.py' \
  --export-markdown inner-loop.md \
  'make test-changed' \
  'make test'
```

Scripts written for hyperfine 1.x need updating.[^hyperfine-200][^hyperfine]

#### Development environments: local, container or cloud

Environment friction shows up as days of setup for joiners, drift between laptops and toolchain help requests.
[PlatformOps](../platformops/) builds them; the choice changes what DevExOps must verify.

| Option | Removes | Adds | Verify with |
|---|---|---|---|
| Local toolchain, scripted setup | Remote start-up waits; works offline | Drift between laptops; setup per joiner | Days to first successful build; setup help requests |
| Local dev container[^devcontainers] | Most drift: the toolchain lives in the repository | A container runtime; laptop limits | The same, plus a one-question prompt after setup[^devex] |
| Cloud environment, such as GitHub Codespaces | Laptop limits; code on laptops; setup time, with prebuilds | A start-up wait; a compute and storage bill; no offline work; code on the provider's machines | Start time P50 and P90; cost per developer-month |

**Start-up.** Prebuilds help when creating a codespace takes "more than 2 minutes", but they cost Actions minutes and
storage.[^codespaces-prebuilds] **Cost.** As of October 2026 a 4-core codespace costs 0.36 USD per active hour and storage 0.07 USD
per GB-month, with no free quota for organisations.[^codespaces-billing] Six active hours a day for 21 days is about 45 USD of
compute per developer a month. **Net effect.** Verify per persona: halving a joiner's setup while adding a three-minute wait to
everyone's morning can be a net loss. **Security.** Before code moves to a provider's machines, check region, access and secrets
with the security owner.

### Methods, standards and frameworks

There is **no standard** and no certification: combine research frameworks, company practices and one vendor framework.

| Framework | Type | Gives you | Use it for | Caveat |
|---|---|---|---|---|
| DevEx dimensions (2023)[^devex] | Research; authors partly at a vendor | Three dimensions; perceptions plus workflows; KPIs | Structuring survey and metrics | Evidence mostly cross-sectional, self-reported[^devex-action] |
| SPACE (2021)[^space] | Research | Five dimensions; use three or more, one perceptual | Checking a dashboard's balance | No fixed metric list |
| GSM and QUANTS[^swe-ch7] | Google practice | Goals → signals → metrics; five trade-off areas | Metrics for one decision | Needs analysts |
| LinkedIn DPH (2023)[^dph] | Company practice, CC BY 4.0 | Precise metric definitions, personas | Copying definitions | Built for thousands of engineers |
| DX Core 4 (2025)[^core4] | Vendor | Speed, effectiveness, quality, business impact | A compact executive set | Uses "diffs per engineer", which the vendor says needs counterweights and no targets |
| CNCF maturity model, measurement aspect[^cncf-pemm] | Community model | Levels from ad hoc to optimizing | Assessing a platform's measurement | Platform-centred |

DORA reports that developer independence, doing tasks without an enabling team, "resulted in a 5% improvement in productivity at
both the team and individual levels" in 2024 research,[^dora-pe] so ask about self-service in the survey.

### Tooling landscape

Examples were checked on 2026-10-16; they are not recommendations.

| Category | Job | Verified examples | Selection criteria and risks |
|---|---|---|---|
| Survey platform | Anonymous periodic and transactional surveys | General survey tools; DevEx vendors such as DX[^core4] | Anonymity thresholds, export, data residency |
| Delivery-system APIs | CI, review and merge events | GitHub REST API for runs and jobs[^gh-runs][^gh-jobs] | Rate limits, field selection, token scope |
| Build analytics | Build timings, cache hits | Vendors of "developer productivity engineering"[^dpe] | Coverage across build tools; lock-in |
| Inner-loop frameworks | Fast edit-deploy-debug on containers | DevSpace, Skaffold, Tilt (listed by Microsoft)[^ms-arc] | Runtime fit; local resources |
| Reproducible environments | Same toolchain everywhere | Dev Container specification; GitHub Codespaces[^devcontainers][^codespaces-prebuilds] | Start time, bill, offline work ([trade-offs](#development-environments-local-container-or-cloud)) |
| Benchmarking | Repeatable command timings | hyperfine[^hyperfine] | Pin the version; control caches |

### Automation and AI

AI coding tools are a **DevEx intervention** and a **measurement trap**.

- **Intervention.** AI assistants change feedback loops and review load; the delivery-level evidence (DORA) is on the
  [DevOps](../devops/#automation-and-ai) page. Watch review load and change failures, not only speed.
- **Trap.** In METR's randomised trial with early-2025 tools, 16 experienced developers in mature repositories they knew well took
  19% longer when AI was allowed, yet estimated that AI had cut their time by 20%.[^metr-paper] Its 2026 follow-up was unreliable
  because developers increasingly refused to work without AI; METR now thinks the speed-up is likely larger but cannot size
  it.[^metr-2026] It warns that "survey results are not necessarily grounded in reality".[^metr-survey] Use system data and
  staged rollouts; ask about experience, not estimated speed-ups.
- **Useful automation.** Field-selected collection, stale-review reminders, free-text summaries checked by a human (models can
  invent themes).

## DevExOps in practice

### Reference implementation

**Assumptions (illustrative):** 250 engineers, 30 teams, five personas, GitHub Actions, a quarterly survey, a three-person DevEx team.

**Artefact 1: metric catalogue**, in version control: definition, source, aggregation and owner per metric.

_Example status: YAML syntax-checked by the Atlas validator; not used against live data._

```yaml
# metrics.yaml: version 4, changed 2026-10-01
# (queue time split out; unplanned-work and help-request metrics added)
metrics:
  - id: ci_feedback_p90
    dimension: feedback_loops
    definition: >-
      Minutes from the first job created to the last job completed,
      per workflow run; P50 and P90
    # created_at, started_at, completed_at only: no actor fields collected
    source: github_actions_jobs
    exclude: [cancelled, skipped]
    aggregation: team_per_month
    # smaller teams merge with a sibling; publish only the merged figure
    min_group: 5
    owner: platform-team
    target: "P90 under 30 minutes"
  - id: ci_queue_p90
    dimension: feedback_loops
    definition: "Minutes from job created to job started; P90; split by hour of day"
    source: github_actions_jobs
    aggregation: runner_pool_per_month
    owner: platform-team
    target: "P90 under 5 minutes in working hours"
  - id: review_response_p50
    dimension: feedback_loops
    definition: >-
      Business hours from each review request, including re-requests after
      new pushes, to the next reviewer response; P50 and P90
    source: pull_request_events
    # shown to the reviewers' managers, as LinkedIn does
    aggregation: reviewing_team_per_month
    # a two-person reviewing team is individual data
    min_group: 5
    owner: engineering-managers
  - id: unplanned_per_engineer_week
    dimension: flow_state
    definition: >-
      Pages, incident assignments and tickets marked unplanned that reach
      the team, divided by its engineers, per week; P50 across the month
    # team counts only: nothing per person, no chat or calendar data
    source: [paging_events, ticket_tracker]
    aggregation: team_per_month
    min_group: 5
    owner: engineering-managers
  - id: onboarding_first_merge_days
    dimension: cognitive_load
    definition: >-
      Median working days from start date to first merged change,
      per quarterly joiner cohort
    source: [hr_start_dates, pull_request_events]
    aggregation: cohort_per_quarter
    min_group: 5
    owner: devex-team
  - id: help_requests_per_persona
    dimension: cognitive_load
    definition: >-
      Questions in tool and platform help channels plus help-desk tickets,
      per 10 engineers of the persona, per month
    # counts only: no message text; askers mapped to a persona, then dropped
    # a rise can also mean people ask sooner instead of struggling: read with CL1
    source: [help_channel_events, ticket_tracker]
    aggregation: persona_per_month
    min_group: 5
    owner: devex-team
```

The review metric follows LinkedIn's "Code Reviewer Response Time": every request counts once, including re-requests after new
pushes, and results go to reviewers' managers because that proved "more actionable".[^dph-metrics]

**Artefact 2: survey instrument** in illustrative wording, not a validated scale: test it in interviews first.

_Example status: YAML syntax-checked; item wording not validated._

```yaml
# survey.yaml: version 2 (2026-Q4).
# Change rule: wording edits need a new item ID and one parallel cycle.
scale: {type: likert, points: 5, favourable: [4, 5]}
min_group: 5
items:
  - id: FL1
    dimension: feedback_loops
    text: "I get CI results quickly enough to stay on the same task."
  - id: FL2
    dimension: feedback_loops
    text: "Reviews of my changes arrive in time for me to keep working."
  - id: CL1
    dimension: cognitive_load
    text: "I can find the documentation I need without asking someone."
  - id: CL2
    dimension: cognitive_load
    text: "Our tools and processes are easy to understand."
  - id: FS1
    dimension: flow_state
    text: "I get enough uninterrupted time for deep work."
  - id: FS2
    dimension: flow_state
    text: "My work holds my interest."
  - id: FS3
    dimension: flow_state
    text: "Unplanned requests rarely pull me away from planned work."
  - id: KPI1
    dimension: outcome
    text: "Overall, it is easy for me to deliver changes."
  - id: TXT1
    dimension: open
    text: "What slowed you down most this quarter?"
```

**Artefact 3: a reproducible development environment** (Development Container specification). `onCreateCommand` runs at creation
or prebuild and "will not typically have access to user-scoped assets or secrets"; `postCreateCommand` runs once the container is
assigned to a user.[^devcontainer-spec]

_Example status: JSON syntax-checked; not built (the Make targets are placeholders; the image tag existed on MCR on 2026-10-16)._

```json
{
  "name": "payments-service",
  "image": "mcr.microsoft.com/devcontainers/python:3.12",
  "features": {"ghcr.io/devcontainers/features/github-cli": {}},
  "hostRequirements": {"cpus": 4, "memory": "8gb"},
  "onCreateCommand": "make deps",
  "postCreateCommand": "make test-changed",
  "forwardPorts": [8080]
}
```

**Artefact 4: least-privilege collection.** Avoid your `gh auth login` session: a classic gh token needs at least `repo`,
`read:org` and `gist`, and gh's manual favours `GH_TOKEN` for fine-grained tokens.[^gh-auth] A fine-grained token with "Actions"
read access to one repository suffices;[^gh-runs][^gh-jobs] give it an expiry, and organisations may require owner
approval.[^gh-pat]

_Example status: syntax-checked with `bash -n`, not executed (needs a repository and a token)._

```bash
# Collect one month of completed pull-request runs and all job attempts;
# keep only timing fields.
read -rsp "Fine-grained token (one repo, Actions: read): " GH_TOKEN
export GH_TOKEN
OWNER=example-org REPO=example-repo RANGE=2026-09-01..2026-09-30
RUNS="repos/$OWNER/$REPO/actions/runs"
QUERY="per_page=100&event=pull_request&status=completed&created=$RANGE"
gh api --paginate "$RUNS?$QUERY" --jq '.workflow_runs[].id' > run-ids.txt
while read -r id; do
  gh api --paginate "$RUNS/$id/jobs?filter=all&per_page=100" \
    --jq '.jobs[] | {run_id, run_attempt, workflow_name, name, conclusion,
           created_at, started_at, completed_at, labels} | @json'
done < run-ids.txt > jobs.jsonl
```

Gotchas: filtered run listings return at most 1,000 results, so split busy months.[^gh-runs] The default `filter=latest` drops
re-run attempts;[^gh-jobs] with `filter=all`, Lab 2 measures from the first attempt to the last, re-run waits included, and runs
with `run_attempt` above 1 are a signal of their own. `gh api` switches to POST when given `-f` fields, hence the query string in
the URL;[^gh-api] date ranges use `YYYY-MM-DD..YYYY-MM-DD`.[^gh-search]

### Hands-on labs

**Lab 1 (beginner): pass the measurement triage.** Objective: turn a complaint into a decision-linked, measurable question.
Prerequisites: a real complaint and 45 minutes; no tools, cost or risk.

1. Write the complaint as a question: "Is waiting for CI the main thing slowing the payments team?"
2. Answer Google's triage questions in a line each: expected result and why; action if the data agrees; action if not; who
   decides, and when.[^swe-ch7] If a negative result changes nothing, stop.
3. Fill a GSM grid: one **goal** without a metric, two or three **signals**, one perceptual and one system **metric** per signal.[^swe-ch7]
4. Check it against SPACE (three dimensions, one perceptual measure)[^space] and add a counter-metric that would reveal harm.

Expected output: one page with question, decider, expected result, actions for both outcomes, a GSM grid and a counter-metric.
Validation: a colleague can name the decision a negative result changes. Troubleshooting: if every metric counts activity, ask
what developers would *feel* if the goal were met. Teardown: none; keep the sheet.

**Lab 2 (intermediate): CI feedback and queue time from job records.** Objective: P50 and P90 feedback time per workflow, queueing
separated from running, the hours when runners are short, and what fixing them would save. Prerequisites: Python 3.8+, no
packages, 20 minutes, local files only; for real data run Artefact 4 first.

_Example status: executed on Python 3.8.10 on 2026-10-16 with the synthetic data below; re-run 2026-10-17 after reformatting, output
unchanged and verbatim._

1. Save the generator (synthetic data: 400 runs, a runner pool saturated from 09:00 to 11:59 UTC):

```python
"""make_jobs.py: write 30 days of synthetic GitHub Actions job records
(jobs.jsonl) for Lab 2."""
import json
import random
from datetime import datetime, timedelta, timezone

random.seed(11)
start = datetime(2026, 9, 1, tzinfo=timezone.utc)
iso = lambda t: t.strftime("%Y-%m-%dT%H:%M:%SZ")
with open("jobs.jsonl", "w") as out:
    for run_id in range(1, 401):
        created = start + timedelta(days=random.randrange(30),
                                    hours=random.choice(range(7, 19)),
                                    minutes=random.randrange(60))
        busy = 9 <= created.hour <= 11  # shared runners saturated mid-morning
        jobs = [("ci", "lint", 1.5), ("ci", "build", 6), ("ci", "test", 11)]
        if run_id % 4 == 0:
            jobs = [("e2e", "e2e", 18)]
        prev_done = created
        for wf, name, mins in jobs:
            # minutes waiting for a runner
            queued = random.expovariate(1 / (7 if busy else 0.6))
            job_created = prev_done if name == "test" else created
            started = job_created + timedelta(minutes=queued)
            done = started + timedelta(minutes=mins * random.uniform(0.8, 1.4))
            prev_done = done if name == "build" else prev_done
            out.write(json.dumps({
                "run_id": run_id, "workflow_name": wf, "name": name,
                "conclusion": "success", "created_at": iso(job_created),
                "started_at": iso(started), "completed_at": iso(done),
                "labels": ["self-hosted", "linux"]}) + "\n")
print("wrote jobs.jsonl")
```

2. Save the report script:

```python
"""ci_feedback.py: CI feedback time and queue time per workflow
from GitHub Actions job records."""
import json
import math
import sys
from collections import defaultdict
from datetime import datetime

def ts(s):
    return datetime.strptime(s, "%Y-%m-%dT%H:%M:%SZ")

def pct(values, q):  # nearest-rank percentile, no interpolation
    v = sorted(values)
    return v[max(0, math.ceil(q * len(v)) - 1)]

def mean(values):
    return sum(values) / len(values)

runs = defaultdict(list)
for line in open(sys.argv[1] if len(sys.argv) > 1 else "jobs.jsonl"):
    job = json.loads(line)
    if job.get("conclusion") in ("success", "failure"):  # skip cancelled, skipped
        runs[(job["workflow_name"], job["run_id"])].append(job)

feedback, queue, queue_by_hour, by_start = (defaultdict(list) for _ in range(4))
for (wf, _), jobs in runs.items():
    first = min(ts(j["created_at"]) for j in jobs)
    last = max(ts(j["completed_at"]) for j in jobs)
    minutes = (last - first).total_seconds() / 60
    feedback[wf].append(minutes)
    by_start[first.hour].append(minutes)
    for j in jobs:
        wait = (ts(j["started_at"]) - ts(j["created_at"])).total_seconds() / 60
        queue[wf].append(wait)
        queue_by_hour[ts(j["created_at"]).hour].append(wait)

print(f"{'workflow':<8} {'runs':>5} {'feedback p50':>13} {'p90':>6} "
      f"{'queue p50':>10} {'p90':>6}")
for wf in sorted(feedback):
    f, q = feedback[wf], queue[wf]
    print(f"{wf:<8} {len(f):>5} {pct(f, .5):>12.1f}m {pct(f, .9):>5.1f}m "
          f"{pct(q, .5):>9.1f}m {pct(q, .9):>5.1f}m")
p90_hour = {h: pct(w, .9) for h, w in queue_by_hour.items()}
worst = sorted(p90_hour, key=p90_hour.get, reverse=True)[:3]
print("worst hours (UTC) by queue p90:",
      ", ".join(f"{h:02d}:00={p90_hour[h]:.1f}m" for h in worst))

peak = [m for h in worst for m in by_start[h]]  # runs started in the worst hours
rest = [m for h in by_start if h not in worst for m in by_start[h]]
for label, v in (("worst-hour runs", peak), ("other runs", rest)):
    print(f"{label:<15} {len(v):>4}  feedback p50 {pct(v, .5):.1f}m  "
          f"p90 {pct(v, .9):.1f}m  mean {mean(v):.1f}m")
# share of all feedback minutes saved if worst-hour runs matched the rest
saved = len(peak) * (mean(peak) - mean(rest)) / sum(peak + rest)
print("feedback minutes saved if worst-hour runs matched the rest: "
      f"{100 * saved:.1f}%")
```

3. Run `python3 make_jobs.py && python3 ci_feedback.py jobs.jsonl`.

Expected output:

```text
wrote jobs.jsonl
workflow  runs  feedback p50    p90  queue p50    p90
ci         300         20.4m  34.0m       0.6m   5.3m
e2e        100         21.1m  27.8m       0.7m   6.8m
worst hours (UTC) by queue p90: 10:00=22.4m, 11:00=18.6m, 09:00=15.6m
worst-hour runs   98  feedback p50 28.4m  p90 48.6m  mean 31.5m
other runs       302  feedback p50 19.4m  p90 23.4m  mean 19.8m
feedback minutes saved if worst-hour runs matched the rest: 12.7%
```

Validation: off-peak runs take a median of 19.4 minutes with a sub-minute queue, so job run time sets the typical wait; runs
started 09:00–11:59 take 28.4 (P90 48.6): morning queues make the tail. Two findings, two owners: run time for service teams and
[TestOps](../testops/), runners for the platform team. A perfect runner fix saves only 12.7% of feedback minutes. Troubleshooting:
with `needs:`, check whether dependent jobs' `created_at` is the run start in your data; if so, their "queue" includes upstream
waits, so measure queue on independent jobs only. Teardown: delete `jobs.jsonl` and `run-ids.txt`; revoke the lab token.

**Lab 3 (advanced): triangulate survey and system data, with suppression.** Objective: favourable shares per dimension and team,
small groups suppressed, agreement classified. Prerequisites: Python 3.8+, 30 minutes, synthetic data only.

_Example status: executed on Python 3.8.10 on 2026-10-17; output verbatim._

1. Save the generator:

```python
"""make_survey.py: synthetic survey answers (1-5) and team telemetry for Lab 3."""
import csv
import random

random.seed(5)
ITEMS = ["FL1", "FL2", "CL1", "CL2", "FS1", "FS2"]
# team: (respondents, mean score per dimension FL, CL, FS)
TEAMS = {"payments": (14, 2.4, 3.9, 3.6), "search": (11, 3.8, 2.5, 3.7),
         "mobile": (4, 2.0, 2.2, 2.9), "platform": (9, 4.0, 3.9, 3.0)}
with open("survey.csv", "w", newline="") as f:
    w = csv.writer(f)
    w.writerow(["team"] + ITEMS)
    for team, (n, fl, cl, fs) in TEAMS.items():
        for _ in range(n):
            means = [fl, fl, cl, cl, fs, fs]
            w.writerow([team] + [min(5, max(1, round(random.gauss(m, 0.8))))
                                 for m in means])
with open("telemetry.csv", "w", newline="") as f:
    w = csv.writer(f)
    w.writerow(["team", "ci_p90_min", "review_p50_hours"])
    w.writerows([["payments", 41, 3.5], ["search", 12, 2.0],
                 ["mobile", 55, 9.0], ["platform", 35, 1.5]])
print("wrote survey.csv and telemetry.csv")
```

2. Save the analysis:

```python
"""triangulate.py: favourable share per DevEx dimension, small-group
suppression, survey vs telemetry."""
import csv
from collections import defaultdict

MIN_GROUP = 5  # suppress any group smaller than this (this Atlas's default)
DIMENSIONS = {"feedback loops": ["FL1", "FL2"], "cognitive load": ["CL1", "CL2"],
              "flow state": ["FS1", "FS2"]}
TARGET = {"ci_p90_min": 30, "review_p50_hours": 4}  # agreed service levels
VERDICT = {(True, True): "agree: slow and felt",
           (False, True): "survey only: interview (unlogged waits?)",
           (True, False): "telemetry only: check the metric",
           (False, False): "agree: fine"}

answers = defaultdict(list)
for row in csv.DictReader(open("survey.csv")):
    answers[row["team"]].append(row)
telemetry = {r["team"]: r for r in csv.DictReader(open("telemetry.csv"))}

print(f"{'team':<9} {'n':>3}  {'feedback':>8} {'cognitive':>9} {'flow':>5}  "
      "feedback-loop check")
for team in sorted(answers):
    rows = answers[team]
    if len(rows) < MIN_GROUP:
        print(f"{team:<9} {'<5':>3}  "
              "suppressed: publish no figure it can be derived from")
        continue
    fav = {}
    for dim, items in DIMENSIONS.items():
        scores = [int(r[i]) for r in rows for i in items]
        fav[dim] = 100 * sum(s >= 4 for s in scores) / len(scores)
    t = telemetry[team]
    slow = (float(t["ci_p90_min"]) > TARGET["ci_p90_min"]
            or float(t["review_p50_hours"]) > TARGET["review_p50_hours"])
    unhappy = fav["feedback loops"] < 50
    print(f"{team:<9} {len(rows):>3}  {fav['feedback loops']:>7.0f}% "
          f"{fav['cognitive load']:>8.0f}% {fav['flow state']:>4.0f}%  "
          f"{VERDICT[(slow, unhappy)]}")
```

3. Run `python3 make_survey.py && python3 triangulate.py`.

Expected output:

```text
wrote survey.csv and telemetry.csv
team        n  feedback cognitive  flow  feedback-loop check
mobile     <5  suppressed: publish no figure it can be derived from
payments   14       18%       68%   57%  agree: slow and felt
platform    9       72%       78%    6%  telemetry only: check the metric
search     11       64%        5%   64%  agree: fine
```

Validation: mobile (four answers) is suppressed although it looks worst: the price of anonymity
(merging rules: [Aggregation](#quality-privacy-security-and-compliance)). Payments is a clean but noisy finding
([14 people](#when-has-a-measure-moved)). Platform's CI is over target yet its developers are content (automated runs nobody
waits for?); its 6% on flow is the real finding. Search's problem is cognitive load, invisible to CI metrics.
Troubleshooting: `KeyError` means a team is missing from `telemetry.csv`. Teardown: delete the two CSV files.

### Use cases and scenarios

All four are documented cases; note their limits.

| Case | Context and problem | Method | Reported result | Trade-offs and pitfalls |
|---|---|---|---|---|
| 1. eBay "Velocity Initiative"[^devex] | Slow feedback, high cognitive load | Quarterly surveys, system data, focus groups; tooling and documentation gaps fixed | Released "twice as frequently"; deployment lead times cut six times | Reported by the paper's DX-linked authors; no independent audit |
| 2. Pfizer[^devex] | Engineering grew nearly tenfold, 2018–2022, in a regulated setting | Quarterly surveys; team insights plus time for local fixes | No outcome numbers; initiatives only (a portal, less duplication, better source-control tools) | Same caveat |
| 3. Google readability[^swe-ch7] | Is a costly code-review certification still worth it? | Triage, GSM, QUANTS; two surveys plus logs | Worthwhile: faster reviews and submits; process then improved | Owners committed in advance to kill it if negative |
| 4. Microsoft Nudge[^nudge] | Overdue pull requests block authors | Predict completion; remind the blocker | Randomised trial, 147 repositories: 60% shorter resolution time for 8,500 overdue pull requests; 73% of reminders rated positive | Reminders interrupt; avoid nagging active reviews |

A cautionary fifth case: Kent Beck recounts that at Facebook, developer-survey scores were rolled up into managers' and directors'
scores and appeared in performance reviews; managers then bargained with engineers for good scores.[^orosz-beck]

## Measure, govern, pay

### Metrics and KPIs

Report P50 and P90 for waits, as LinkedIn does;[^dph-metrics] long waits dominate experience,
so medians alone mislead.

| KPI | Definition or formula | Data source | Pitfall | Review |
|---|---|---|---|---|
| CI feedback time | Last job completed − first job created, per run; P50, P90 | CI job records | Averages hide the long tail | Monthly |
| CI queue time | Job started − job created; P90 by hour | CI job records | Dependent jobs may include upstream waits (Lab 2) | Monthly |
| Local build time | Human-triggered builds only, P50 and P90 (LinkedIn's "Developer Build Time")[^dph-metrics] | Build-tool telemetry | Counting automated builds[^swe-ch7] | Monthly |
| Review response time | Business hours, each review request → next response; P50, P90[^dph-metrics] | Pull-request events | Speed becomes rubber-stamping; pair with a quality item | Monthly |
| Onboarding time | Median working days, start → first merged change, per cohort | HR start date, VCS | Tiny cohorts identify people | Quarterly |
| Unplanned work | Pages, incident assignments and unplanned tickets reaching a team, per engineer-week | Paging, tickets | Counting a person's chats or calendar is monitoring | Monthly |
| Favourable share | Answers of 4 or 5 ÷ all answers to a dimension's items | Survey | Comparing cultures with different response styles[^space] | Each cycle |
| Response rate | Responses ÷ invited, per team | Survey | Low rates bias toward the motivated | Each cycle |
| Findings verified | Findings closed with a measure moved beyond its agreed threshold ÷ findings closed | Backlog | Closing on "shipped", or on noise | Quarterly |

**Leading and lagging.** Satisfaction "could serve as a leading indicator for productivity"; retention lags and is confounded by pay
and promotion.[^space]

**Worked calculation (illustrative numbers): do morning runners pay?** A 240-engineer organisation sees Lab 2's pattern in its
own data. The proposal: two engineer-weeks (80 hours) of set-up, then 3,000 a month (any currency).

1. **Exposure.** About 960 CI runs a day × the **mean** feedback time of 22.7 minutes ≈ **363 hours a day** (means for totals,
   percentiles for experience). Exposure is not loss: people switch tasks.
2. **Reported loss.** The **mean** survey answer for "hours lost waiting on builds and CI last week" is 2.5: 240 × 2.5 = **600
   hours a week**: a self-report, which can be badly wrong,[^metr-survey] and includes local builds, which runners do not touch.
3. **Break-even.** Assume, conservatively, half the reported loss is CI and a third of that is real; the runners remove at most
   Lab 2's **12.7%** of it: 600 × 1/2 × 1/3 × 0.127 ≈ **12.7 hours a week**, about 660 a year. Against 36,000 a year (12 × 3,000) plus the 80
   set-up hours, they pay in year one only if an engineer-hour costs more than about **62** (36,000 ÷ (660 − 80)); from year two,
   more than about **55** (36,000 ÷ 660). Often it does, but the case is modest; a survey item separating local from CI waits
   would test both assumptions.
4. **Bigger lever.** Job run time is most of the other 87%: cutting it by a fifth saves about 16%. Raise both findings; the
   runners still remove the tail that FL1 answers feel.
5. **Verify** next quarter: queue P90 at 10:00 under 5 minutes **and** an FL1 change beyond the agreed threshold, or reopen.


#### Measuring flow and cognitive load, not only waits

Waits are the easiest friction to log, so dashboards drift toward them (the streetlight effect[^swe-ch7]). "DevEx in Action"
measured flow by deep-work time, "frequency of interruptions" and interesting tasks, and cognitive load by ease of deploying,
understanding code and using tools.[^devex-action] So pair FS1 and FS3 with the unplanned work reaching each team per
engineer-week, and CL1 and CL2 with onboarding time and help requests per persona (Artefact 1). After a flow fix such as
"clustering meetings, avoiding unplanned work, and batching help requests",[^devex] expect both flow measures to move beyond their
thresholds while review and help response times hold: SPACE warns that fewer interruptions can "block others' work".[^space]

#### When has a measure moved?

"Verify, don't assert" needs a rule for telling change from noise. This Atlas's rule, written into the finding **before** the fix:

1. **Target and threshold.** Name the metric, group, comparison period and the change that counts as moved.
2. **Small groups are noisy.** Lab 3's 18% for payments (5 of 28 answers) comes from 14 people; a 95% Wilson interval, with
   people as the unit, runs from about 6% to 44%.[^nist-ci] For platform's 72% from 9 people it is 40–91%. At team size a 20-point
   change can be noise: require the same direction in two cycles, pool teams given the same fix, or let the system measure decide.
3. **Like with like.** Same weeks and hours, comparable volume (runs, builds, reviews), unchanged definitions.
4. **Regression to the mean.** Teams chosen because they scored worst tend to score better next time even without a fix;[^barnett-rtm]
   compare with teams not yet given the fix, which a staged rollout provides.
5. **Response rate and mix.** If the response rate or persona mix changed between cycles, say so: the comparison is weaker.

### Quality, privacy, security and compliance

DevEx data is employee data. Orientation as of October 2026, **not legal advice**.

- **Aggregation.** SPACE notes that in some countries individual productivity reporting is not legal.[^space] This Atlas suggests
  suppressing groups under five, which alone can leak: if a team is hidden but its sibling and their parent total are published,
  subtraction reveals it. Statisticians add "secondary suppression" against "disclosure by differencing";[^ukhsa-sdc] also allow
  one breakdown per report (team or persona, not team × persona × tenure).
- **Germany.** Works councils have a co-determination right over "the introduction and use of technical devices designed to monitor
  the behaviour or performance of the employees" (Works Constitution Act, section 87(1) no. 6, in the ministry's English
  translation; only the German text is official).[^betrvg] Telemetry pipelines can fall under it.
- **United Kingdom.** ICO guidance covers "productivity tools which log how workers spend their time"; outside very exceptional
  covert cases "you must inform workers about any monitoring", and an impact assessment may be required. The guidance is under
  review after the Data (Use and Access) Act.[^ico]
- **European Union.** The AI Act lists AI systems used "to monitor and evaluate the performance and behaviour of persons" at work
  as high-risk (Annex III, point 4(b));[^aiact-annex3] the 2026 AI Omnibus moved these obligations to 2 December 2027.[^ai-omnibus]
  An AI system meant to score engineers' performance would likely be covered; get legal advice.
- **Security.** Read-only, least-privilege tokens; field selection; logged access to mapping tables; scheduled deletion. Free text
  can identify authors: review it before quoting it or sending it to an external AI service.
- **Quality.** Check biases SPACE flags, such as review sentiment differing by gender and time normalisation that penalises people
  on leave.[^space]

### Cost, capacity and sustainability

Costs are people (in this page's judgement, a lead and a researcher at minimum), tools and developers' time. One vendor's survey
takes a median of 10 minutes,[^devex-action] so 250 people × 10 minutes × 4 cycles ≈ 167 hours a year (median-based): cheap with
action, waste without. Fixes cost too: cloud environments bill compute and storage
([environments](#development-environments-local-container-or-cloud)); runners cost money and energy, so add them for the hours
that queue (Lab 2), not all day.

### Assurance of the operating model

Quarterly indicators: response rate by team; findings verified beyond their threshold; median days from finding to verified fix;
disagreements investigated; instrument changes; mapping-table access log. Yearly, retire or rotate any metric people now optimise
directly (Goodhart's Law, which CNCF's top measurement level expects teams to know[^cncf-pemm]).

## When things go wrong

### Common failures and troubleshooting

| Symptom | Likely cause | Diagnosis | Remediation | Prevention |
|---|---|---|---|---|
| Response rate falls each cycle | No visible action[^devex] | Owned findings of the last two cycles | "You said, we did" readout | Owned findings every cycle |
| Dashboard improves, survey worsens | Metric misses the felt wait, or friction moved | Experience sampling; split by persona | Fix the definition; add the missing measure | Validate metrics qualitatively[^swe-ch7] |
| Trend jumps | Wording or definition changed | Instrument changelog | Restate or restart the series | Change control |
| Teams contest results | Managers saw results first | Who saw what, when | Teams first | Readout order in the policy |
| Leaders ask for per-person data | Performance pressure | Request log | Decline; offer aggregates | Ban written in before launch |
| Survey says friction, telemetry silent | Friction not instrumented | Interviews | Write the finding anyway | Accept perceptual evidence |

### Worked runbook: CI got faster, developers say it got worse

**Situation (illustrative).** After a platform team cut CI P50 from 20 to 12 minutes, the next survey shows FL1 favourable falling
from 55% to 41% across 240 respondents. At that size the two 95% intervals (49–61% and 35–47%) do not overlap: the fall is
real.[^nist-ci]

1. **Contain.** Do not announce "CI is 40% faster"; say you are investigating.
2. **Check the instrument.** Same wording, scale and invitation list? If not, the series is broken: stop. A changed response rate
   weakens the comparison.
3. **Break down** both measures by persona and team: often most improved and one (say, mobile) got worse.
4. **Check what the metric excludes:** the queue, the P90, another runner pool (run Lab 2 on that persona's workflows).
5. **Ask in context:** two weeks of experience sampling for that persona, one question per finished CI run.
6. **Decide.** A metric that missed the wait gets a new definition and a restated trend; friction that moved (say, to review
   queues) becomes a new finding for its owner.
7. **Verify and record.** The original finding closes only when both measures agree.

**Prevention:** publish each fix's effect per persona.

### Anti-patterns and myths

- **Rewarding measured activity**, such as per-person commits or pull requests: it gets gamed.[^swe-ch7][^orosz-beck]
- **One "DevEx score" as a target.** LinkedIn: "Resist the temptation to aggregate metrics into scores"; one metric's gain can
  hide another's loss.[^dph-scores]
- **Borrowed targets.** Vendor percentiles, or McKinsey's "Top tech companies aim for developers to spend up to 70 percent of
  their time doing inner-loop activities", given without a source;[^mckinsey] use your own trend.
- **Myth: developers reject measurement.** SPACE notes they value tracking their own productivity.[^space]

## Deciding and adopting

### When to use and when not to use

**Use it when** several teams share tools, so one fix helps many; platform, tooling or AI investments need a baseline; or
complaints are frequent but contradictory.

**Not yet, or not at all, when** the group is small enough to discuss friction weekly (a retrospective is cheaper); nobody will act on
a negative result, or a reorganisation will soon invalidate the baseline;[^swe-ch7] the real goal is judging individuals (a
[PeopleOps](../peopleops/) question with legal duties); or trust is too low for honest answers: fix that first.

**Hidden costs:** policy and consultation work, analysts, reporting back every cycle.

### Decision framework

::: figure Should you start a DevExOps loop, and with which instrument?
```mermaid
---
config:
  flowchart:
    wrappingWidth: 110
    nodeSpacing: 30
---
flowchart TB
  A{"Judge individuals?"}
  N1["Stop: a PeopleOps question"]
  B{"Decider will act?"}
  N2["Secure a decider first"]
  C{"Teams share tools?"}
  N3["Retros and a friction log"]
  D{"Wait data exists?"}
  E["Survey plus system data"]
  F["Survey first, add data later"]
  A -->|"yes"| N1
  A -->|"no"| B
  B -->|"no"| N2
  B -->|"yes"| C
  C -->|"no"| N3
  C -->|"yes"| D
  D -->|"yes"| E
  D -->|"no"| F
  classDef decision fill:#fdf3e3,stroke:#c9800f,color:#122029
  classDef risk fill:#fbeceb,stroke:#b4332b,color:#122029
  classDef core fill:#e8f3f2,stroke:#16756f,color:#122029
  classDef neutral fill:#f1f4f6,stroke:#5b7a87,color:#122029
  class A,B,C,D decision
  class N1,N2 risk
  class N3 neutral
  class E,F core
```
Text equivalent: Four questions in sequence. Judging individuals? Stop: a PeopleOps question. Will a decider act on any result?
If not, secure one first. Do several teams share tooling? If not, use retrospectives and a friction log. Is wait data available? If
yes, survey plus system data; if not, survey first and instrument later.
:::

The tree encodes this page's assumptions.

### Maturity model

This is **this Atlas's model**, not a standard; the idea of measurement levels comes from the CNCF model.[^cncf-pemm]

| Level | Observable behaviour | Exit criteria |
|---|---|---|
| 1. Anecdotal | Friction known through complaints; the loudest voice wins | A named decider and a data-use policy |
| 2. Baselined | One survey with stable items and two or three system metrics | Second survey, same items; three owned findings |
| 3. Looping | Quarterly cycle; personas; findings verified before closing | Half of closed findings verified beyond their threshold |
| 4. Integrated | Transactional prompts, experience sampling; SLOs for developer-facing systems | Survey-log disagreements investigated each cycle |
| 5. Adaptive | Staged rollouts for big interventions (AI tools, platforms) | Gamed metrics retired; results used in investment cases |

### Adoption roadmap: 30/60/90 days

| Window | Actions | Milestone |
|---|---|---|
| Days 1–30 | Sponsor and decider; data-use policy drafted with privacy (and any works council); personas; Lab 1 for the top three complaints; CI job data (Artefact 4) | Policy approved; baseline telemetry |
| Days 31–60 | Survey from validated items, five pilot interviews, two-week window; Labs 2 and 3 | Response rate published; readouts to every team |
| Days 61–90 | Three findings with owners, targets and thresholds; quick wins (peak-hour runners, a broken setup step, stale-review reminders) | First "you said, we did" note; next survey date set |

## Toolkit

### Checklists

**Before the first survey**

- [ ] Decision and decider written down
- [ ] Data-use policy approved; ban on performance-review use stated
- [ ] Works council or employee representatives consulted where required
- [ ] Minimum group size and personas fixed
- [ ] Items piloted in interviews; IDs and versions assigned

**Each cycle**

- [ ] Same items and metric definitions as last cycle, or changes logged
- [ ] P50 and P90 reported; small groups suppressed, and nothing they can be derived from
- [ ] Survey-versus-telemetry disagreements listed and assigned
- [ ] Readout to teams before leadership
- [ ] Every finding has an owner, metric, target and verification date

**Yearly governance audit**

- [ ] Mapping-table access log reviewed; raw rows past retention deleted
- [ ] Each metric checked for gaming; retired or rotated where needed
- [ ] Instrument reviewed by someone outside the DevEx team

### Templates

**One-page DevExOps charter**

```text
Purpose:      Reduce developer friction measurably; never evaluate individuals.
Decider:      <name, role>          Sponsor: <name, role>
Scope:        <teams, personas>
Out of scope: Performance reviews, individual ranking
Instruments:  Survey v<n> (quarterly); metrics.yaml v<n>;
              transactional prompts at <touchpoints>
Cadence:      Survey <month>; monthly metric review; findings triage every 2 weeks
Data use:     Aggregates only; minimum group <5>; retention <months>;
              access: <roles>
Success:      <n> findings verified per quarter; KPI "ease of delivery" trend
Review:       Charter and instrument reviewed every <12> months
```

**Finding record**

```text
ID / title:     DX-<year>-<n>: <one line>
Evidence:       Survey <item, favourable %, group>; system <metric, P50/P90, period>
Affected:       <personas, teams, approx. people>
Hypothesis:     <cause>
Owner / due:    <team> / <date>
Target:         <metric> from <x> to <y>; <item> favourable from <a>% to <b>%
Moved if:       <threshold set now: beyond interval | same direction 2 cycles>
Compared with:  <teams not yet given the fix>; response rate then/now <a>% / <b>%
Verification:   <cycle or date>; result: moved | within noise | reopened
```

**Data-use policy clauses**

```text
1. Purpose: improving tools, processes and working conditions for groups of
   developers.
2. Never used for: performance ratings, promotion, pay, dismissal or ranking
   of individuals or teams.
3. Reporting: groups of <5> or more only; no published figure may let a
   suppressed group be derived; free text reviewed before quoting.
4. Access: raw data limited to <roles>; access logged and reviewed <yearly>.
5. Retention: raw rows deleted after <n> months; aggregates kept.
6. Changes: any new data source or use requires approval by <privacy owner>
   (and the works council where applicable).
```

### Deep comparisons

Scores 1–3 are this page's judgement. High cost is bad and high precision good, so weight them with opposite signs: with
precision × 2 − cost, telemetry and experience sampling score 4, a prompt 3, a periodic survey 2 and interviews −1. Yet interviews
win when the question is "why": weights must follow the question.

| Instrument | Sees | Misses | Cost per cycle (3 = highest) | Precision (3 = highest) | Best for |
|---|---|---|---|---|---|
| Periodic survey | Perceptions, unmeasured friction, culture | Exact durations; non-respondents | 2 | 2 | Baselines, trends, KPIs |
| Transactional prompt | Experience at a touchpoint | The rest of the day | 1 | 2 | Specific tools and flows |
| System telemetry | Exact waits at scale | Why; whether anyone waited | 2 | 3 | Feedback-loop metrics |
| Experience sampling | Lived experience in context | Breadth; it interrupts | 2 | 3 | Validating metrics |
| Interviews | Causes, stories | Representativeness | 3 | 1 | Explaining surprises |

### FAQ

**Is DevExOps a real job title?** No published use was found; for the names such teams use, see [At a glance](#at-a-glance).
Judge a team by what it measures and who ships the fixes.

**Can we measure individual developers "just for coaching"?** SPACE allows opt-in individual analysis for developers' own use;
reporting upward differs, and Google found that metrics used in performance reviews get gamed.[^space][^swe-ch7]

**We have 30 engineers. Do we need this?** Probably not as a programme: a retrospective question, a friction log and timings of
your slowest commands will do.

**Our survey says all is fine, but delivery is slow. Who is right?** Possibly both: developers can be content with needlessly
slow builds.[^devex] Our inference: people stop noticing waits they consider normal. Check the P90s, then
interview.

**Should we buy a DevEx platform?** Buy anonymity, validated items and integrations if you lack survey expertise; distrust
vendors' benchmarks and reported results.[^core4] A spreadsheet and Lab 3 suffice for a first cycle.

## Going further

### Advanced topics and emerging direction

- **Agents in the inner loop.** As agents write and test code, waiting may shift from builds to reviewing their output; METR found
  time measurements unreliable for developers running several agents at once.[^metr-2026] Review load may become a key metric (a
  reasoned expectation).
- **Causal evaluation.** Randomised reminders (Nudge) and staged rollouts beat before-and-after surveys as evidence.[^nudge]
- **Validated instruments.** "DevEx in Action" publishes its items and reliability statistics;[^devex-action] calls to formalise
  the field may produce shared scales.[^combemale]

### Learning path

| Stage | Do this |
|---|---|
| 1 day | Read the DevEx and SPACE papers; do Lab 1 on your top complaint |
| 1 week | Run Lab 2 on your own CI data; time your slowest inner-loop command |
| 30 days | Draft the data-use policy and a 15-item survey; pilot it in five interviews; run Lab 3 |
| Advanced | Experience sampling; a staged rollout of a fix; Google's GSM chapter; LinkedIn's metric definitions |
| Portfolio | A metric catalogue, a versioned survey and one finding verified beyond its threshold |

## Wrap-up

### Executive recap and cheat sheet

| Topic | Remember |
|---|---|
| The term | Rare, unstandardised; the field is developer experience; here, a measure-prioritise-verify loop |
| Model | Feedback loops, cognitive load, flow state; SPACE to keep metrics balanced |
| Instruments | Stable survey + system data; interviews when they disagree |
| Metrics | P50 and P90 for waits; favourable shares; unplanned work; onboarding time; findings verified |
| Verification | Threshold set before the fix; small teams need two cycles or pooling; beware regression to the mean |
| Ethics | Teams and personas only; suppress small groups and their differences; never in performance reviews |
| Owners | DevExOps diagnoses and verifies; PlatformOps, teams and leaders fix |
| Next actions | Name a decider; write the data-use policy; run Labs 1–3; publish three owned findings |

### A judgement call: CI capacity or documentation first?

**Situation (illustrative).** You have one platform engineer for a quarter. Telemetry shows a 22-minute CI queue P90 at peak.
The survey shows cognitive load worst for three of five personas: only 28% can find documentation without asking. Leadership
prefers the CI fix because the dashboard will show it. **Assumptions:** both problems are confirmed; the CI fix is mostly runner
capacity; documentation needs owners, not only writing.

**Reasoning.**

1. *Attractive but incomplete:* choosing CI because it is measurable is the "streetlight effect" Google's GSM method warns
   against.[^swe-ch7]
2. *Effort:* morning runner capacity is days of work plus a running cost, not a quarter.
3. *Evidence:* the uneven "DevEx in Action" result above favours cognitive load,[^devex-action] but one cross-sectional study
   shifts the odds without settling the question.
4. *Verification:* documentation fixes are harder to verify, so design measures first: a transactional prompt on the top ten pages,
   onboarding time per cohort, and CL1 favourable share pooled across the three personas.

**Decision.** Buy runner capacity now (verified next month by the queue P90) and spend the engineer-quarter on documentation for
the three personas, with owners and that plan. **Uncertainty:** if the documentation measures have not moved past their thresholds
after two cycles, reopen the finding rather than declare victory.

### Learning objectives and mastery check

After this page you can **explain** why DevExOps is an ambiguous label; **design** a survey and metric catalogue that balance
perceptions and system data; **compute** waits, favourable shares and their noise; **operate** a quarterly loop with verification;
and **evaluate** requests for productivity data against ethics and law.

::: answer 1. A director asks for each engineer's pull-request count to "find low performers". What do you answer, and why?
Decline; offer team aggregates. Activity metrics should never be used alone to reward or penalise (SPACE), and metrics used in
performance reviews get gamed (Google). German works councils may have a say, and AI that evaluates performance is likely high-risk
under the EU AI Act. Performance belongs to PeopleOps.
:::

::: answer 2. Median CI feedback time is 12 minutes, but people say CI is slow. Name two checks before arguing.
The P90, including queue P90 by hour, because tails drive experience; and whether the metric covers the waits people feel (queue,
re-runs, a persona's runner pool), checked with experience sampling.
:::

::: answer 3. Your second survey reworded four items "for clarity". What happened to your trend?
It broke for those items: a change in experience is now confounded with a change in wording. Give reworded items new IDs, run old
and new in parallel for a cycle, and log the change.
:::

::: answer 4. A team of four has the worst scores. Do you publish them?
No: it is below the minimum group. Merge it with a sibling and publish only the merged figure, since a published sibling or parent
total would reveal it by subtraction; or use interviews, with consent.
:::

::: answer 5. After an AI assistant rollout, 80% of developers say they are faster. Is the rollout a success?
Not proven: self-reported speed-ups have proved unreliable. Compare cycle time, review queue and change failures between enabled
and not-yet-enabled teams, and ask about experience rather than estimated speed.
:::

::: answer 6. Which page owns building the fix for a slow golden-path template, and what does DevExOps still do?
PlatformOps builds and runs the fix. DevExOps supplies the evidence, sets the verification metric and its threshold in advance, and
closes the finding only when the next measurement moves beyond it.
:::

### Conclusion

"DevExOps" is a label without a community, but the work it can name is real and under-done: treating developer friction as an
operational signal that is measured, owned and verified, not a mood to guess or a score to game. The research is good enough to act
on, within its stated limits. The hard part is not the
dashboard but the discipline: measure only what someone will act on, report back every time, keep the data away from individual
judgement, and call a fix done only when the next measurement clears the noise. Do those four things and the name matters little.

## Sources and further reading

Sources were opened on the dates shown (Internet Archive copies where live pages blocked access). Product and legal facts are as
of October 2026; claim-level support is in the evidence ledger.

[^devex]: [DevEx: What Actually Drives Productivity](https://queue.acm.org/detail.cfm?id=3595878) — Abi Noda and others, ACM Queue 21(2), 2023-05-03 (Internet Archive copy). Checked 2026-10-17.
[^space]: [The SPACE of Developer Productivity](https://queue.acm.org/detail.cfm?id=3454124) — Nicole Forsgren and others, ACM Queue 19(1), 2021-03-06 (Internet Archive copy). Checked 2026-10-16.
[^devex-action]: [DevEx in Action: A study of its tangible impacts](https://queue.acm.org/detail.cfm?id=3639443) — Nicole Forsgren and others, ACM Queue 21(6), 2024-01-14 (Internet Archive copy). Checked 2026-10-17.
[^greiler]: [An Actionable Framework for Understanding and Improving Developer Experience](https://arxiv.org/abs/2205.06352) — Michaela Greiler, Margaret-Anne Storey, Abi Noda, arXiv 2022 (IEEE TSE). Checked 2026-10-16.
[^fagerholm]: [Developer Experience: Concept and Definition](https://arxiv.org/abs/1312.1452) — Fabian Fagerholm, Jürgen Münch, ICSSP 2012 (arXiv author version). Checked 2026-10-16.
[^combemale]: [Towards a Science of Developer eXperience (DevX)](https://arxiv.org/abs/2506.23715) — Benoit Combemale, arXiv, 2025-06-30. Checked 2026-10-16.
[^swe-ch7]: [Measuring Engineering Productivity (chapter 7)](https://abseil.io/resources/swe-book/html/ch07.html) — Ciera Jaspan, *Software Engineering at Google*, O'Reilly, 2020 (online edition). Checked 2026-10-16.
[^dph]: [LinkedIn Developer Productivity and Happiness Framework](https://github.com/linkedin/dph-framework) — LinkedIn, CC BY 4.0; repository history from 2023-09-29, last change 2024-01-15. Checked 2026-10-17.
[^dph-blog]: [Practical Magic: Improving Productivity and Happiness for Software Development Teams](https://www.linkedin.com/blog/engineering/developer-experience-productivity/improving-productivity-and-happiness-framework-open-source) — Max Kanat-Alexander, Grant Jenks, LinkedIn Engineering, 2023-12-19. Checked 2026-10-16.
[^dph-metrics]: [Example Metrics](https://github.com/linkedin/dph-framework/blob/main/example-metrics.md) — LinkedIn DPH Framework. Checked 2026-10-16.
[^dph-scores]: [What's wrong with "scores?"](https://github.com/linkedin/dph-framework/blob/main/scores.md) — LinkedIn DPH Framework. Checked 2026-10-17.
[^dph-personas]: [Developer Personas](https://github.com/linkedin/dph-framework/blob/main/developer-personas.md) — LinkedIn DPH Framework. Checked 2026-10-16.
[^core4]: [Measuring developer productivity with the DX Core 4](https://getdx.com/research/measuring-developer-productivity-with-the-dx-core-4/) — Abi Noda and others, DX (vendor), undated. Checked 2026-10-16.
[^infoq-core4]: [DX Core 4 framework](https://www.infoq.com/news/2025/01/dx-core-4-framework/) — InfoQ news, 2025-01-06. Checked 2026-10-16.
[^dora-pe]: [Capabilities: Platform engineering](https://dora.dev/capabilities/platform-engineering/) — DORA (Google Cloud), updated 2026-01-12. Checked 2026-10-16.
[^dora-2024]: [Accelerate State of DevOps Report 2024](https://dora.dev/research/2024/dora-report/) — DORA, 2024 (summary page). Checked 2026-10-16.
[^cncf-pemm]: [Platform Engineering Maturity Model](https://tag-app-delivery.cncf.io/whitepapers/platform-eng-maturity-model/) — CNCF TAG App Delivery, v1 October 2023. Checked 2026-10-16.
[^ms-inner]: [Understand the Inner Loop](https://learn.microsoft.com/en-us/training/modules/implement-tools-track-usage-flow/2-understand-inner-loop) — Microsoft Learn, updated 2026-06-17. Checked 2026-10-16.
[^ms-arc]: [Inner loop developer experience for teams adopting GitOps](https://learn.microsoft.com/en-us/azure/azure-arc/kubernetes/conceptual-inner-loop-gitops) — Microsoft Learn, 2025-01-23. Checked 2026-10-16.
[^mckinsey]: [Yes, you can measure software developer productivity](https://www.mckinsey.com/industries/technology-media-and-telecommunications/our-insights/yes-you-can-measure-software-developer-productivity) — Chandra Gnanasambandam and others, McKinsey, 2023-08-17 (Internet Archive copy). Checked 2026-10-17.
[^orosz-beck]: [Measuring developer productivity? A response to McKinsey](https://newsletter.pragmaticengineer.com/p/measuring-developer-productivity) — Gergely Orosz and Kent Beck, The Pragmatic Engineer, 2023-08-29. Checked 2026-10-16.
[^google-review]: [Speed of Code Reviews](https://google.github.io/eng-practices/review/reviewer/speed.html) — Google Engineering Practices. Checked 2026-10-16.
[^nudge]: [Nudge: Accelerating Overdue Pull Requests Towards Completion](https://arxiv.org/abs/2011.12468) — Chandra Maddila and others, ACM TOSEM 2022 (arXiv version). Checked 2026-10-16.
[^metr-paper]: [Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity](https://arxiv.org/abs/2507.09089) — METR, arXiv, 2025-07-12. Checked 2026-10-16.
[^metr-2026]: [We are Changing our Developer Productivity Experiment Design](https://metr.org/blog/2026-02-24-uplift-update/) — Joel Becker and others, METR, 2026-02-24. Checked 2026-10-16.
[^metr-survey]: [Measuring the Self-Reported Impact of Early-2026 AI on Technical Worker Productivity](https://metr.org/blog/2026-05-11-ai-usage-survey/) — METR, 2026-05-11. Checked 2026-10-17.
[^devcontainers]: [Development Containers](https://containers.dev/) — Development Container Specification. Checked 2026-10-16.
[^devcontainer-spec]: [Dev Container metadata reference](https://containers.dev/implementors/json_reference/) — Development Container Specification. Checked 2026-10-16.
[^codespaces-prebuilds]: [About GitHub Codespaces prebuilds](https://docs.github.com/en/codespaces/prebuilding-your-codespaces/about-github-codespaces-prebuilds) — GitHub Docs. Checked 2026-10-16.
[^codespaces-billing]: [GitHub Codespaces billing](https://docs.github.com/en/billing/concepts/product-billing/github-codespaces) — GitHub Docs. Checked 2026-10-16.
[^gh-runs]: [REST API endpoints for workflow runs](https://docs.github.com/en/rest/actions/workflow-runs) — GitHub Docs (API version 2026-03-10). Checked 2026-10-16.
[^gh-jobs]: [REST API endpoints for workflow jobs](https://docs.github.com/en/rest/actions/workflow-jobs) — GitHub Docs (API version 2026-03-10). Checked 2026-10-16.
[^gh-api]: [gh api](https://cli.github.com/manual/gh_api) — GitHub CLI manual. Checked 2026-10-16.
[^gh-auth]: [gh auth login](https://cli.github.com/manual/gh_auth_login) — GitHub CLI manual. Checked 2026-10-16.
[^gh-pat]: [Managing your personal access tokens](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens) — GitHub Docs. Checked 2026-10-16.
[^gh-search]: [Understanding the search syntax](https://docs.github.com/en/search-github/getting-started-with-searching-on-github/understanding-the-search-syntax) — GitHub Docs. Checked 2026-10-16.
[^hyperfine]: [hyperfine README](https://github.com/sharkdp/hyperfine) — David Peter and contributors. Checked 2026-10-16.
[^hyperfine-200]: [hyperfine v2.0.0 release](https://github.com/sharkdp/hyperfine/releases/tag/v2.0.0) — GitHub release, 2026-10-07. Checked 2026-10-16.
[^betrvg]: [Works Constitution Act (Betriebsverfassungsgesetz), English translation](https://www.gesetze-im-internet.de/englisch_betrvg/englisch_betrvg.html) — language service of the Federal Ministry of Labour and Social Affairs, to the 19 July 2024 amendment; the German text is the official one (Internet Archive copies). Checked 2026-10-16.
[^aiact-annex3]: [Annex III: High-Risk AI Systems Referred to in Article 6(2)](https://artificialintelligenceact.eu/annex/3/) — EU AI Act Explorer (Future of Life Institute), reproducing Regulation (EU) 2024/1689. Checked 2026-10-16.
[^ai-omnibus]: [The AI Digital Omnibus Regulation has been published](https://www.garrigues.com/en_GB/garrigues-digital/ai-digital-omnibus-regulation-has-been-published-redefining-deadlines-and) — Garrigues (law firm), 2026-07-24. Checked 2026-10-16.
[^ukhsa-sdc]: [Data management in official statistics policy](https://www.gov.uk/government/publications/ukhsa-official-statistics-compliance-documents/data-management-in-official-statistics-policy) — UK Health Security Agency, GOV.UK, updated 2026-04-01. Checked 2026-10-16.
[^nist-ci]: [Confidence intervals (for a proportion)](https://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm) — NIST/SEMATECH e-Handbook of Statistical Methods, 7.2.4.1. Checked 2026-10-16.
[^barnett-rtm]: [Regression to the mean: what it is and how to deal with it](https://doi.org/10.1093/ije/dyh299) — Adrian Barnett and others, International Journal of Epidemiology 34(1), 2005 (abstract via Europe PMC). Checked 2026-10-16.
[^ico]: [Employment practices and data protection: monitoring workers](https://ico.org.uk/for-organisations/uk-gdpr-guidance-and-resources/employment/monitoring-workers/data-protection-and-monitoring-workers/) — UK Information Commissioner's Office (guidance under review). Checked 2026-10-16.
[^leaddev-team]: [What is a developer experience team?](https://leaddev.com/velocity/what-developer-experience-team) — Abi Noda (DX founder), LeadDev, 2022-10-03. Checked 2026-10-16.
[^tt-concepts]: [Key Concepts](https://teamtopologies.com/key-concepts) — Team Topologies (Matthew Skelton, Manuel Pais), undated. Checked 2026-10-16.
[^yash]: [DevOps services (DevXOps)](https://www.yash.com/services/infrastructure-management-services/devops/) — YASH Technologies, undated. Checked 2026-10-16.
[^roblox]: [Roblox Developer Exchange Program](https://create.roblox.com/docs/production/monetization/developer-exchange) — Roblox Creator Hub documentation. Checked 2026-10-16.
[^dpe]: [Ebooks and whitepapers](https://develocity.ai/resources/ebooks-and-whitepapers/) — Develocity (Gradle); gradle.com's DPE page redirects here. Checked 2026-10-16.

**Changelog.**

- 2026-10-16 — r0: first version by the managing author. Labs 2 and 3 executed on synthetic data; artefact commands not executed.
- 2026-10-16 — r1: after the independent review (`reviews/devexops-r1.md`): noise rule; Lab 2 and the worked calculation
  corrected; development environments; complementary suppression; dates, definitions, author ties and legal wording corrected.
- 2026-10-17 — r2: after the independent score (`reviews/devexops-score.md`): code blocks rewrapped to fit the column, labs
  re-run; break-even includes set-up effort; P50/P90 rationale attributed; flow measures added; figures re-laid out.
- 2026-10-17, post-score polish: after `reviews/devexops-score-r2.md`: habituation marked as inference; reported-loss total uses
  the mean, no "upper bound"; help-request metric defined; figure 3 redrawn; anti-patterns consolidated.
