of real usage · sessions across projects · generated
How to read this report. Anything tagged measured comes from Claude Code session records and git history — it is reproducible and auditable. Anything tagged assumption depends on an estimate of how long a developer would have taken by hand, which cannot be measured after the fact. Those assumptions are adjustable on this page: move the controls and every number recalculates.
Time attributed to development work over the measured period:
hours per calendar day across days. See methodology for the full reconciliation between this figure and the hours of raw session duration.
This is the central question: how much goes into building the feature, and how much into everything else. Each hour is attributed to the activity in progress at that moment, reconstructed from the chronological record of every session.
Against the initial hypothesis.
No hour in this report is extrapolated from a sample. Each is a sum of intervals between recorded events. The table below decomposes every category into number of operations × average duration, so any line can be checked independently.
Average duration is the most useful sanity check here: test runs averaging and builds/lint averaging are consistent with what those operations actually cost, which indicates the time attribution is not inflated.
Time falls into two distinct regimes. During active work Claude Code is executing and the developer follows along. During interaction time the tool is idle, waiting on a human — this is where reviewing the result and manual testing live.
On manual testing. The hours classified as manual testing are a floor, not a total. They count only the pauses where the developer's next message showed evidence of hands-on testing — a pasted screenshot, an error report, a confirmation that something worked. Manual testing done silently, or after a session ended, appears in no record. See instrumentation for how to measure this directly.
The hypothesis that mature projects spend proportionally more effort on tests holds, and holds strongly. Each dot is a project; dot size is total hours in it. The line is the hours-weighted fit.
How maturity is computed. A 0–100 index combining three independent signals taken from the repository itself: source size (weight 35%), age of git history (25%), and the ratio of test lines to source lines (40%). It is deliberately crude — its job is to order projects along an axis, not to be an absolute measure.
This is where the analysis stops being measurement. How long the same work would have taken without the tool does not exist in the data — it can only be modelled. So two independent models are presented, with visible and adjustable assumptions. They answer different questions and land on very different numbers; the distance between them is itself informative.
For each measured activity, how many times longer a developer would take doing the same thing by hand. Assumes the same work and the same decisions — the conservative scenario.
Applies a human authoring rate, in lines per hour, to the lines that actually landed in the repositories. Assumes the entire delivered scope would have been written by hand — the upper bound.
Why the two models diverge so widely.
The measured coefficients put to practical use: describe a project's size and profile and the page projects hours per activity, using the rates and maturity adjustments observed across the projects in the fitted sample.
Own projects with at least one hour of attributed time.
Raw session duration is far larger than attributed time, because long gaps are not work. Nothing is discarded silently — the arithmetic closes:
pytest, node --test or mvn test is test
execution; editing .md is documentation, and so on. The complete rules
live in classify.py.before_after.json, but the data does not support a
conclusion: What retrospective analysis cannot see is manual testing and review time spent outside a session. That is directly measurable with hooks installed in the projects, which record the timestamp of each work cycle. The repository ships the hooks and installation instructions; once installed, future editions of this report will have manual test time measured rather than estimated as a floor.
Generated by build_report.py from report_data.json. Pipeline:
analyze.py → repo_metrics.py → git_delta.py →
before_after.py → model.py → build_report.py.