Research note 03
What Is a Task
Solvency's calculator asks "how many tasks?" Measured across 60 shipped GitHub repos in six use cases, a solo mobile app ships in dozens of tasks (median 48); a data/ML pipeline needs hundreds (median 479).
- Published
- 2026-08-25
- Prices verified
- 2026-08-21
- Sources
- GitHub (gh api) · Artificial Analysis
- Method
- merged PRs or commits, repo creation to first non-draft release
Every table in this note is re-derived from the datasets by the test suite.
What Is a Task
Six use cases, 60 shipped repos, one operational definition. Solvency’s calculator and Build Composer both ask “how many tasks?” as their volume input. Until now nothing on the site said what a task is or how many a real project needs. This note answers both questions from measured GitHub history, in the same spirit as the other two notes: numbers over adjectives, sources linked, gaps stated plainly.
The short version
A task is one bounded, reviewable unit of change with a checkable outcome — the same unit coding benchmarks already measure, and the same unit an AI agent attempt targets. It is not a new concept invented for this note; it is the unit Solvency’s cost-per-solved-task math already runs on (see Cost Per Solved Task).
Measured across 60 open-source repos from creation to first shipped release, task counts vary by two orders of magnitude within every bucket and by use case: a solo mobile app typically ships in dozens of tasks (median 48), a data/ML pipeline in hundreds (median 479). The spread inside each bucket is as wide as the spread between buckets — which is itself informative: task count is a weak function of category and a strong function of scope, team size, and how a project defines “first release.”
1. The definition
One task = one bounded, reviewable unit of change with a checkable outcome. In practice, that is one issue-to-patch cycle: a defined problem, a diff that addresses it, and a pass/fail check (tests, review, or both) that decides whether it’s done.
This is not a bespoke definition. It’s the unit the benchmarks Solvency already ingests use:
- Artificial Analysis Coding Agent Index scores pass@1 over a fixed task set — each task is one closeable unit of work an agent either solves or doesn’t.
- SWE-bench-style benchmarks are built directly from issue→patch cycles: a real GitHub issue, the PR that closed it, and the tests that verify it.
- OpenBench task trials (used in Same Model, Six Harnesses) count discrete admission-gated tasks per harness run.
So “a task” in this note, in the calculator, and in Solvency’s cost-per-solved-task tables is the same unit. That continuity is the point: if the site tells a visitor a build needs 80 tasks and separately tells them a solved task costs $3.81, those two numbers are meant to compose.
What this note adds: benchmarks define the unit but not the volume. Nobody publishes “how many of these units does a mobile app take.” That’s an empirical question about real shipped software, not about model performance — which is what section 2 measures.
2. The measurement
Method. GitHub proxy study, 60 shipped repos across 6 use-case buckets, queried
2026-08-24/25 UTC via recorded gh api calls (data/task-study/measure_repo.sh, repo list
in data/task-study/repos.txt).
Unit chosen per repo:
- Merged PRs, if the repo runs a PR-review flow: contributors > 3, ≥ 10 merged PRs, and a PR/commit ratio ≥ 0.15.
- Commits, otherwise (solo or near-solo repos where most work lands as direct commits, not reviewed PRs).
Window: repo creation to first non-draft GitHub release. Five repos had no discoverable first-release milestone consistent with normal development — their history reads as imported (migrated from another VCS, or bulk-imported) rather than built up commit-by-commit in this repo. For those five, the count falls back to lifetime totals, which measures total project activity rather than time-to-v1.
Cross-bucket summary
| Bucket | n | Median | Q1–Q3 | Range |
|---|---|---|---|---|
| Marketing/landing site | 10 | 248 | 62–650 | 10–14,344 |
| Full web app (SaaS) | 11 | 306 | 150–327 | 56–1,609 |
| 2D indie game | 10 | 240.5 | 54–479 | 19–1,681 |
| CLI tool/utility | 9 | 133 | 21–316.5 | 12–1,825 |
| Data/ML pipeline | 9 | 479 | 97.5–1,654 | 8–19,723 |
| Mobile app | 11 | 48 | 22–113 | 18–288 |
Source data: data/task-study/final_table.csv, 60 rows, one per repo, generated by
data/task-study/measure_repo.sh against the public GitHub API. Q1/Q3 are Tukey hinges: the
median of the lower half and the median of the upper half of each bucket’s sorted counts, with
the bucket median itself excluded from both halves when a bucket has an odd number of repos.
Example repos per bucket
Marketing/landing site (PostHog/posthog.com, monicahq/marketing_site, cruip/open-react-template) — 14,344 merged PRs; 331 merged PRs; 13 commits.
Full web app (SaaS) (documenso/documenso, chatwoot/chatwoot, formbricks/formbricks) — 1,609 merged PRs; 202 merged PRs; 56 commits.
2D indie game (deathkiller/jazz2-native, fishfolk/jumpy, Walkator/Kailius) — 1,681 commits; 192 merged PRs; 19 commits.
CLI tool/utility (eza-community/eza, charmbracelet/gum, google/zx) — 1,825 commits; 133 commits; 14 merged PRs.
Data/ML pipeline (cloudquery/cloudquery, bruin-data/ingestr, turbot/steampipe) — 19,723 merged PRs; 479 merged PRs; 8 commits.
Mobile app (openfoodfacts/smooth-app, maxrave-dev/SimpMusic, rafsoh/dimeApp) — 288 merged PRs; 48 commits; 18 merged PRs.
3. Caveats
Stated in full, because a methodology section that only lists strengths is marketing.
- Commit/PR granularity varies enormously, repo to repo and author to author. One team’s “task” is a single 2,000-line commit; another’s is ten 50-line PRs for the same change. This note counts units, not effort — it does not normalize for size.
- AI-assisted tasks are probably finer-grained than these human-authored histories. Agent workflows tend to decompose work into smaller, more frequently checked units than a solo human committing at their own pace. That means these counts are more likely lower bounds on AI-driven task counts than direct equivalences — a project an AI agent tackles may take more discrete tasks than the human history that shipped the same category of product, not fewer.
- Survivorship bias. Every repo here shipped a first release. Abandoned projects — which never accumulate a countable “time to v1” — are invisible to this method entirely.
- “First release” is a fuzzy milestone, and it explains much of the within-bucket spread. Some maintainers tag v0.0.1 after a week; others wait a year and ship v1.0 fully formed. The same underlying amount of work can read as 20 tasks or 200 depending on tagging habits alone.
- Five repos have no reliable first-release milestone and are measured as lifetime totals instead of time-to-v1. Their counts overstate “tasks to first ship” for whatever their actual v1 was, because they include everything that came after.
- Curated, not randomly sampled. These 60 repos were selected to be recognizable, popular, and cleanly attributable to one of six buckets — not drawn at random from GitHub. A random sample would likely show different medians and almost certainly a different (probably wider) range.
- Bucket (a), marketing/landing sites, is half landing-page template products (astro/Next.js starter templates, Tailwind boilerplates) rather than genuine bespoke marketing sites, because open-source examples of the latter are scarce — most company marketing sites are closed-source. That mix pulls the bucket’s low end down and makes it less representative of “build me a marketing site for my product” than the other five buckets are of their categories.
4. How to use it
Worked example 1 — solo mobile app. Bucket f, Q1–Q3 is 22–113 tasks, median 48. At Claude Opus 5’s measured rate of $12.01 per solved task (Artificial Analysis Coding Agent Index v1.4, read 2026-08-21 — see Cost Per Solved Task), a solo mobile app to first ship is roughly:
22 tasks × $12.01 = $264
48 tasks × $12.01 = $576 (median)
113 tasks × $12.01 = $1,357
≈ $264–$1,357, median ≈ $576, using one frontier model at its measured cost-per-solved-task figure. This is a translation of the volume number into a dollar range, not a project bid — see the caveats above on what “task” does and doesn’t normalize for.
Worked example 2 — CLI tool. Bucket d, Q1–Q3 is 21–316.5 tasks, median 133. Swapping in DeepSeek V4 Flash’s measured rate of $0.12 per solved task (same source, same read date) instead of a frontier model:
21 tasks × $0.12 = $2.52
133 tasks × $0.12 = $15.96 (median)
316.5 tasks × $0.12 = $37.98
≈ $2.52–$38, median ≈ $16. The 100x model-choice gap documented in Cost Per Solved Task shows up directly once a task-volume estimate is attached to it — the same task count, priced at two different models, is a two-order-of-magnitude difference in dollars.
5. Product tie
This task-count table is the evidence behind the volume input the calculator and Build Composer ask for — when a visitor picks a use case, these numbers are what should populate the default task-count range instead of a guess.
Reproduce this
cat data/task-study/final_table.csv # raw per-repo data, 60 rows
cat data/task-study/measure_repo.sh # the gh api calls that produced each row
cat data/task-study/repos.txt # the 60 repos, bucketed a–f
npm test # test/task-report.test.ts re-derives every figure
Every summary figure in section 2 is directly re-derivable from final_table.csv’s
count_used column, grouped by bucket. No number in this note is interpolated or modeled —
every task count comes from a gh api response; every dollar figure in section 4 comes from a
row in data/models.json or a headline number already published in
Cost Per Solved Task.
Data queried 2026-08-24/25 UTC via the GitHub API (data/task-study/). Model prices verified
2026-08-21 against provider pricing pages, so the source and price do not appear fresher than
they are.