How they build it: agent-driven development at 39 PRs/day

This chapter is the review's most novel content, because it is the part no product page shows. dsh is a live demonstration of how DeepSeek runs a large monorepo with agents doing most of the work.

Velocity

From git log:

Metric Value
First commit b67e81ac97, 2026-06-10
Upstream HEAD 47f943859b, 2026-08-13
Elapsed 64 calendar days, all 64 with commits
Non-merge commits 6,684 (~104/day)
Total incl. merges 12,294
Highest PR number #2521 (~39 PRs/day)
Author concentration one author 34%, top three 58%, ~20 total

The branch namespaces tell the story: merges come from worktree/* (306) and codex/* (203) prefixes — parallel git worktrees and Codex-authored PRs — plus agent/*. A sample subject: "Merge pull request #2512 from deepseek-harness/codex/2503-english-onboarding-copy". This is a small human team amplified by a fleet of agents running in isolated worktrees.

The commit-type histogram shows the cost of that speed: 33.6% fix: against 10.3% feat: — 3.3 fixes per feature, a build-then-repair signature consistent with high-throughput agent generation. The counterweight is discipline: 94.5% of commits follow conventional-commit format, and the revert rate is 0.40%.

The .agents/ tree: 28% of the repo, unexplained in the README

2,078 tracked files — 28% of the repository by file count, 22% by bytes — live under .agents/ and are never mentioned in the README. They are two things:

Agent Notes (.agents/notes/, 2,057 files). A decision-record corpus. .agents/notes/README.md:5: "An Agent Note records a decision or proposal that affects this codebase — the why and what we gave up, the parts code and docs can't carry." Path grammar is {lifecycle}/{class}/yyyy-mm-dd-topic-title.md with a closed lifecycle (proposed/implemented/rejected + frozen archived/) and a closed class set (feature/bug-fix/simplification/architecture/process/testing). There are 686 English source notes, roughly 714k English words, doubled by Chinese translations. Writing one is mandatory: AGENTS.md:122"Non-trivial changes MUST include an Agent Note in the same PR; only mechanical/local edits are exempt." They deliberately declined to automate the trivial/non-trivial judgment with a CI gate (that decision is itself recorded, in .agents/notes/implemented/process/2026-07-19-require-agent-notes-for-non-trivial-changes.md:11).

Skills (.agents/skills/, 11 workflows). These are loaded by the harness at runtime — .agents/skills is a first-class project skill root (packages/skill/skill-filesystem/src/index.ts:247), so running dsh inside this checkout auto-discovers DeepSeek's own internal workflows. They are the most revealing artifact in the repo:

The skills target two vendor harnesses at once — Claude Code and Codex — with optional agents/openai.yaml sidecars kept aligned by scripts/verify-skill-invocation-metadata.ts. This is dogfooding taken to its limit: their internal agent-authoring rules ship in the exact format their product consumes.

The .agents/ warts

The documentation machine

The doc system is genuinely more elaborate than most production repos:

The doc machine's blind spot

For all that machinery, the drift we found clusters in the generated and gated docs, not the hand-written ones — the theme developed in weaknesses.html. Additionally:

Testing

The test story is strong. 216 of 219 packages have a tests/ directory (the three without are defensible: a type-only utility, a tiny service seam, a demo). 762 spec files, plus the build scripts test themselves (45 spec files under scripts/). The seven vitest configs are not redundancy — they are disjoint lanes separated by cost, credentials, and artifact dependency (.spec.ts unit, .e2e.ts token-spending real-API, .snapshot.ts replay, three web lanes), each with an explanatory header. Skipped tests are almost nonexistent: 8 across the whole repo, 6 of them conditional-on-platform-or-key, and zero .only, .todo, or .fails. The test-support packages provide a scriptable OpenAI-compatible mock server and a session-replay harness, and the policy is sound (docs/testing.md:23: "Mock only the expensive or non-deterministic boundary ... keep everything downstream real").

The headline coverage gate is 100% per-file — "100% or it doesn't merge" (vitest.config.ts:269). But it is substantially hollowed out for the client half: of 69 exclusion paths, 51 are packages/client/*, self-labeled as debt with four TODO(gui) blocks. One exclusion is a negated glob (everything except one file). The gate is true for the host/core half and materially untrue for Client, extensions, self-modification, and the Typert generator. There are also 631 v8 ignore comments repo-wide (each must carry a reason, but 631 is a large number against a "100%" claim) and two silent describe.skip blocks in the least-gated file in the repo, the Typert catalog generator.

CI and release

CI security hygiene is above average: an explicit, reasoned ban on pull_request_target (.github/workflows/e2e.yml:20-24), an always() verdict job so a skipped required check cannot read as passing, and trusted-branch policy checkout. But the current CI has real gaps:

Release discipline, by contrast, is a highlight. Three independent publish families (dsh, vendored Cordis, native landlock-run). Publication is decided per package against the registry by tarball integrity — missing gets published, identical gets skipped, differing fails the run (scripts/release/publish.ts:5-8) — and every tarball is installed into a throwaway consumer outside the repo with the bin driven before release (scripts/release/verify-packed-install.ts:14-17). There is exactly one dependency patch in the entire 221-package tree (pnpm-workspace.yaml:71-72, an additive node-pty env override, not a bug fix) — remarkable restraint.

The developer-preview churn is visible in the version line: eight release(dsh) commits landed on 2026-08-13 alone, the base version jumped 0.0.1-rc.5 → 0.1.0-rc.1 the same day (so the rc counter restarted, and 0.1.0-rc.4 never existed), and the "publish publicly" flip (8c1e8d9890) landed mid-sequence — anyone who installed an early rc got a different package-visibility contract than later ones.

Process cost

one non-trivial change the code edit + Agent Note (.md) — mandatory + Chinese twin (.zh.md) + hash record (.i18n.yaml) internal PR ~39 per day merge gates ~30 doc verifiers (run-gates DAG, 14 modes) 100%-per-file coverage (hollowed for client) bilingual sync via custom git merge driver blocking Windows lane = Wine on Ubuntu conventional commits (94.5% observed) → master — where pushes currently get almost no hosted post-merge validation
The marginal cost of one non-trivial change: three extra files and a translation review, then ~30 gates.

The machinery is not free. There are 158 files under scripts/ (35 verify-*, 17 gen-*, 12 translation-*), a 787-line knip config, an issue-management system of 1,119 lines for a repo that accepts no external contributions, and a whole CI workflow whose only job is to reject filenames containing "golden". Much of it is well-organized (a single run-gates.ts DAG orchestrates the verify scripts into 14 named modes, with a cycle detector). But the marginal cost of a non-trivial change is real: source edit, plus an Agent Note, plus its Chinese translation, plus hash records — three extra files and a translation review, every time.