13 — PACKAGE SELECTION POLICY
Depends on: 12_AI_WORKFLOW.md · Next: 14_PRODUCT_SPECIFICATION.md
Every dependency must be scored. Only ≥90/100 installs.
1. When This Applies
- Adding ANY new dependency (including transitive via
pnpm add) - Upgrading a major version
- Approving a transitive override via
pnpm.overrides
2. Scorecard (Fill for EVERY candidate)
### Package: <name> — <purpose>
| Criterion | Weight | Score (0-10) | Evidence |
|---|---|---|---|
| Maintenance (last publish, commit) | 20% | | `pnpm view <pkg> time` + GitHub last commit |
| Security (OSV, advisories, provenance) | 20% | | `api.osv.dev` + `pnpm audit` + `dist.attestations` |
| License (allowlist) | 15% | | `pnpm licenses list`, GitHub LICENSE |
| Popularity (downloads, stars, dependents) | 15% | | `api.npmjs.org` + GitHub stars |
| Quality (issues, bus factor, maintainers) | 15% | | GitHub issues + `pnpm view maintainers` |
| Alternatives considered | 15% | | List 2 alternatives + why this wins |
| **TOTAL (weighted)** | 100% | | |
**Decision:** Install / Reject
**Reason:** ...
**Expiry review:** <date, e.g., 3 months>
Example — alternatives to evaluate:
- Validation:
zodvsvalibotvsarktype→zodwins (ecosystem, OpenAPI) - Auth:
better-authvsauth.jsvslucia→ score each - Charts:
echartsvsrechartsvsvisx→ score - Search:
meilisearchvstypesensevsorilisearchvs Postgres FTS → Postgres wins Phase 1
3. Pass Thresholds
| Score | Action |
|---|---|
| 90-100 | ✅ Install — log in PROJECT_MEMORY.md |
| 75-89 | ⚠️ Install only with written justification + review date |
| <75 | ❌ Reject — pick alternative |
| Any criterion = 0 | ❌ Auto-reject (e.g., archived repo, GPL in shipped code) |
4. Automated Gates
# After any add, must be:
pnpm audit --prod --audit-level=high # 0 high/critical
pnpm licenses list --prod # allowlist only
pnpm dlx knip # 0 unused
If any fails → pnpm.overrides or replace parent dep. Every override gets comment + removal reminder.
5. Freshness Enforcement
pnpm-workspace.yamlcatalog:— single source, no driftminimumReleaseAge=1440— 24h cooling for supply-chain blast windowrenovate.json— weekly automerge patch/minor, separate major PRsscripts/deps-check.sh— runs §4, wired to CI weekly cron
6. Allowlist & Denylist
Allowlist: MIT, Apache-2.0, BSD-2/3, ISC, 0BSD, BlueOak-1.0.0, CC-BY-4.0
Denylist shipped: GPL, AGPL, SSPL, RSALv2 (hence Valkey over Redis ≥7.4 server)
Post-install scripts: onlyBuiltDependencies: [sharp, argon2, esbuild, prisma] — justify each
Next: 14_PRODUCT_SPECIFICATION.md — full feature inventory.