package-extractionlisted
Install: claude install-skill voidcorp-core/void-harness
# package-extraction
Use when you are tempted to move code out of `apps/<app>/src/` into a new `packages/<name>/`. The instinct is good — sharing is virtuous — but **80% of extractions are premature** and end up creating coupling without the reuse benefit.
This skill is the gate. Composes with `harness-monorepo:service-package` (which is the creation workflow once you've decided yes).
## When this skill triggers
- "Let's extract this into a package so both apps can use it"
- "This helper is generic, it shouldn't live in apps/"
- "We're duplicating this in apps/web and apps/mobile"
- Any review comment "extract to packages/"
## The 3-question gate
Extract if and only if **all three** answers are yes:
1. **Are there ≥ 2 distinct consumers RIGHT NOW** (not "maybe later")? Distinct = different `apps/<name>/` packages.
2. **Would inlining the code in both apps cost > 30 minutes of duplication discipline per change**? If a 5-line helper diverges, the answer is no.
3. **Does the code own a CONCEPT, not just a function?** "billing engine" yes. "string utilities" no — those are scattered helpers, not a package.
If you can't say yes to all three, **inline the code in each app instead**. Duplication is cheaper than the wrong boundary.
## When NOT to extract
- ✗ Code used in only one app, "in case we need it later" — YAGNI, extract when the second consumer appears
- ✗ Helpers that wrap a single library function (`isValidEmail(s) { return z.string().email().safeParse(s).success