Depth is a stable working set, not chair time

Non-developers imagine deep work as typing for hours. Developers know most of the time is holding context: failing test, hypothesis, three files, breakpoint, uncommitted diff, last command, seed data quirk. Depth means keeping that set stable long enough to change the system and prove it. Anything that dumps the set without saving state is not a break. It is a restart tax.

Before you call a block deep, name the set: hypothesis, failing test and command, files in play, dirty state, env quirks, done artifact. Size the block to your compile-test loop. End with a park card so tomorrow's restart is cheap. Calendar defense belongs in protect two uninterrupted hours and protect focus at home. This page owns the developer-only wedge.

The working-set checklist

Before you call a block "deep," name the set you are protecting:

  1. Hypothesis in one sentence
  2. Failing (or characterizing) test and the exact command to run it
  3. Files in play (aim for a handful, not the whole repo)
  4. Dirty state - uncommitted diff or stash note
  5. Env quirks - flag, account, port, seed
  6. Done artifact - what reviewable thing ends the block

If you cannot name those, you are browsing, not in depth. Cap active code threads at one unless you are explicitly doing triage. Park other threads with branch name, ticket link, and next command in the ticket - not in your head (restart coding where you left off tomorrow).

What counts as a deep block

A block counts when it produces one reviewable artifact:

  • Pull request with tests and description
  • Repro steps and logs attached to a ticket
  • Design doc section with decision recorded
  • Performance trace with before/after numbers
  • Staging verify notes with accounts and flag state

Reading Slack is not depth. Reviewing twenty tiny pull requests back-to-back is shallow unless that was the planned outcome - and large unfamiliar diffs deserve their own review block, not notification snacking. Shallow reviews feel helpful and create rework, which is the expensive form of context switching.

Size the block to the loop

Match length to your compile-test cycle - not to a generic productivity blog.

Short loop (unit tests in seconds): forty to fifty minutes may suffice if you can stack two blocks with a break.

Long loop (integration suite, container rebuild): plan ninety minutes, or stack so machine waits carry admin - not a second feature. Starting a second feature during an eighteen-minute test run is how both threads die.

Pomodoro for client work helps pick intervals without worshipping twenty-five minutes. Pick one block length for the week and defend it against calendar nibbles. Changing interval every day is its own switch cost. When twenty-five minutes is too short for your loop, see when a 25-minute Pomodoro is too short.

Invest in shortening the loop (local runners, fast linters, IDE indexing) before another productivity book. Keep a personal checklist for new repos: clone, env file, seed command, test command - one note in the ticket saves twenty minutes of rediscovery next month.

Worked examples

Afternoon feature after morning reviews: Batch reviews 09:00-10:30. Feature work 10:45-12:30 with one hypothesis on checkout tax. At 10:40 write in the ticket: "Next: assert on line 88 in TaxServiceTest, branch feat/tax-line." At 12:25 commit or stash with failing output pasted. The afternoon can restart without rereading the entire diff - depth preserved across a boundary.

Long test loop day: Integration tests take eighteen minutes. Schedule ninety-minute blocks: one run, one fix attempt, one run, park note. Between runs do ticket hygiene or walk - not a second feature.

Wrong day type: Release day, triage day, and onboarding weeks are shallow by design. Forcing a feature block into release day creates double failure. Name the day: depth, review, or coordination (plan a developer day with review and feature work).

Reviews, chat, and standups dump the set

Pull request reviews interrupt depth. Batch them into a labeled window or you pay setup tax twice: once to leave depth, once to return. Same for "quick questions" - cheap for the asker, expensive mid-loop (interruptions during debugging). When async review stalls on a shared-model problem, decide whether remote pairing is worth the calendar cost.

If standup is mid-block, park first or schedule standup at block edges. Reporting progress while holding a fragile model often loses the model for a status sentence that could wait thirty minutes.

Shared repos mean shared interrupts. Agree review windows and incident tiers so depth is not a solo hobby. One person in permanent depth while others ping freely creates resentment and shallow fixes.

End blocks like you mean to return

Before standup or lunch:

  • Commit or stash with message
  • Paste failing test output if still red
  • Write next physical action in ticket
  • Note env quirks (account, flag, port)
  • Document the test command for future sessions

Tomorrow's you is a teammate (leave work someone else can continue). Pushing to staging with notes is a valid end-of-block artifact even before merge - checkpoint if tomorrow interrupts.

Measure merges and coherence, not chair time

Track finished artifacts per week, not hours at IDE. If hours rise and merges flatline, you are leaking context or doing invisible rework. Sitting ten hours with chat open produces shallow churn. Depth is how long the working set stays coherent. Twelve "quick" checks are twelve mini-shifts - count them as coordination hours, not feature hours.

Refactors need the same artifact bar as features. "Cleaned up code" without tests or measurable outcome is activity. Green tests on a branch nobody can use yet is progress, not completion - define done with user-visible or integration criteria (green CI is not finished work). Five tiny tickets in five contexts can exceed one medium feature (five small tickets harder than one feature).

Structured pairing keeps one working set shared. Unstructured "can you hop on?" does not. Instrumentation and metrics work need their own plan line - sneaking them inside a feature block yields shallow instrumentation.

Deep work for developers is maintaining a working set until the system changes with evidence. Protect that set like production data - and use the calendar tactics elsewhere so this page can stay about the set, not the furniture.

Working-set dump drill (practice once)

Pick a safe afternoon. Mid-block, deliberately open Slack for two minutes, then close it. Write down what fell out of your head: the failing assertion text, the file you were about to edit, the hypothesis. That list is your personal dump signature - what you must park before any interrupt.

Next real interrupt, park those exact fields first. Two minutes of park beats forty minutes of archaeology. If your dump signature is always "which test was red," make the test command the first line of every park card.

Operating rule: name the working set before you call a block deep; end with a park card (hypothesis, failing test command, files, dirty state, next physical action). Chair time with a dumped set is coordination - not depth. Calendar defense lives in protect two uninterrupted hours.