---
id: "lib-2026-10-28-one-engineer-moved-170-repos-to-pnpm-11"
type: "library"
title: "One engineer moved 170+ repos to pnpm 11"
title_original: "엔지니어 1명이 레포 170여 개를 pnpm 11로"
lang: "KO"
org: "Channel Talk (tech.channel.io)"
source_type: "Practitioner post"
date: "2026-10-28"
week: "2026-W44"
url: "https://nosov.ai/library/lib-2026-10-28-one-engineer-moved-170-repos-to-pnpm-11/"
original_url: "https://tech.channel.io/kr/articles/db0bc143"
tier: "A"
tier_name: "Strong evidence"
tier_reason: "Channel Talk engineer documents a 7-week, agent-run migration of 171 repositories with dated PR counts, a layered regression harness and the pnpm pitfalls found; specific, checkable and candid about what the AI got wrong."
summary_basis: "full-text"
original_minutes: "12"
tags: ["ai technology", "supply chain security", "agent harness", "review capacity"]
frames: ["verification-capacity"]
---

# One engineer moved 170+ repos to pnpm 11

Original title: 엔지니어 1명이 레포 170여 개를 pnpm 11로

Tier A (Strong evidence): Channel Talk engineer documents a 7-week, agent-run migration of 171 repositories with dated PR counts, a layered regression harness and the pnpm pitfalls found; specific, checkable and candid about what the AI got wrong.

Summary based on the full text.

## In short

A Channel Talk tech blog post (28 October 2026) by a web engineer. After the ChainDrop npm worm in August 2026 stole credentials through install scripts, he decided to move all of the team's active JS and TS repositories to pnpm 11, which blocks dependency install scripts by default. Over seven weeks, AI agents did the per-repo work under a harness of written contracts, separate grader agents and machine-checkable regression layers. He set direction, made the policy calls and handled reviews and merges. The commands needed already existed in pnpm; the work was verifying that they did what was expected in every repo.

## Key numbers

- 171: repositories that got a pnpm 11 PR, 26 August to 14 October 2026, by one engineer alongside other work
- 94 (36 merged): of those, repos moved from npm or yarn, with merges as of 20 October
- 234: PRs opened: 130 merged, 89 open, 15 closed unmerged (as of 20 October)
- 5 h 45 min to 1 h 53 min: logged working time for one 10-repo wave, as handover notes accumulated
- 8: policy decisions the engineer made himself (version pinning, allow-list rules and similar)

## What it reports

- Trigger: on 4 August 2026 maintainer accounts for packages pulled in by ESLint (keyv, flat-cache) were taken over and infected versions ran a preinstall script that stole npm, GitHub and cloud credentials; hundreds of packages were hit within hours. The team's lockfiles had no infected versions, which he calls luck.
- Settings per repo: pnpm 11.24.0 (above 10.27.0, which fixed two CVEs), `strictDepBuilds` on, and `allowBuilds` as an object with version-pinned keys so a new version must be re-approved.
- Pitfalls found: writing `allowBuilds` as an array silently allows nothing; `packageManager` is ignored where no tool enforces it, and CI, a shared setup action (defaulting to pnpm 8) and Dockerfiles each ran different versions, so "done" meant the version printed in CI logs.
- `pnpm import` re-resolves versions instead of copying the old lockfile; pnpm ignores npm `overrides` and pnpm 11 ignores yarn `resolutions`, which brought an old vulnerable version back into one lockfile.
- Allow lists must be measured in Linux containers: one repo showed 0 install scripts on macOS and 3 on Linux. A conversion script based on version rules wrongly allowed esbuild and protobufjs in one repo, so the real pre-migration run list became the reference.
- A pnpm 8-format lockfile read by pnpm 10 changed 99 versions in one repo; converting through pnpm 9 first changed none across 18 repos.
- Top-level node_modules fell from 441 to 29 in one repo while regression checks passed; the AI recorded the number but named the wrong cause, and a human PR reviewer found it (ignored `.npmrc` settings).
- The first plan failed twice. Five rules followed, including: resolve unknowns before starting, run once each in local, CI, Docker and the existing repo state, and tag every claim as documented, measured or guessed.
- Regression check in four layers on before and after commits in one container: installed versions, executed install scripts, build output hashes, and the repo's own lint, typecheck and tests. Each layer was first tested with a planted one-version or one-byte change.

## How they got it

The author's record of the project, with PR counts dated 20 October, wave timers and the harness design. The executing AI and the grading AIs were kept separate.

## Limits

- Many PRs were still open at publication; only 36 of the 94 npm/yarn moves had merged.
- The defence covers dependency install scripts only, not the repo's own scripts or a compromise of an already allowed package; a one-line config change can turn it off, so a periodic scan checks six disabling settings.
- Some pnpm behaviour was observed on 11.24.0 and may differ in later versions.

## Why it matters for companies

This is a concrete template for using agents on fleet-wide maintenance, including security hardening after a supply-chain incident. The control points are the transferable part: contracts with one-line pass checks, a grader separate from the executor, regression layers validated with planted faults, and policy decisions kept with a human. The post also shows the residual risk: a passing check and exit code 0 did not prove a setting was active, so every claim was verified by running it.

## Key passages in translation

> 당시 살펴본 저희 레포의 lockfile에는 감염된 버전이 없었습니다. 운이 좋았을 뿐입니다.

The lockfiles in our repos that we checked at the time had no infected versions. We were simply lucky.

> 실행한 AI가 자기 결과를 채점하면 놓친 것을 또 놓칩니다.

If the AI that did the work grades its own result, it misses what it missed again.

> 설정을 넣었다고 켜지지는 않았고 exit 0과 CI 통과 표시도 아무것도 보장하지 않았습니다.

Adding a setting did not turn it on, and exit 0 and a passing CI badge guaranteed nothing.

Original: https://tech.channel.io/kr/articles/db0bc143
