@ryuenn3123/agentic-senior-core 1.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/.agent-context/blueprints/api-nextjs.md +184 -0
  2. package/.agent-context/blueprints/aspnet-api.md +247 -0
  3. package/.agent-context/blueprints/ci-github-actions.md +226 -0
  4. package/.agent-context/blueprints/ci-gitlab.md +200 -0
  5. package/.agent-context/blueprints/fastapi-service.md +210 -0
  6. package/.agent-context/blueprints/go-service.md +217 -0
  7. package/.agent-context/blueprints/graphql-grpc-api.md +51 -0
  8. package/.agent-context/blueprints/infrastructure-as-code.md +62 -0
  9. package/.agent-context/blueprints/kubernetes-manifests.md +76 -0
  10. package/.agent-context/blueprints/laravel-api.md +223 -0
  11. package/.agent-context/blueprints/nestjs-logic.md +247 -0
  12. package/.agent-context/blueprints/observability.md +227 -0
  13. package/.agent-context/blueprints/spring-boot-api.md +218 -0
  14. package/.agent-context/policies/llm-judge-threshold.json +20 -0
  15. package/.agent-context/profiles/platform.md +13 -0
  16. package/.agent-context/profiles/regulated.md +13 -0
  17. package/.agent-context/profiles/startup.md +13 -0
  18. package/.agent-context/prompts/init-project.md +86 -0
  19. package/.agent-context/prompts/refactor.md +45 -0
  20. package/.agent-context/prompts/review-code.md +47 -0
  21. package/.agent-context/review-checklists/architecture-review.md +70 -0
  22. package/.agent-context/review-checklists/frontend-usability.md +33 -0
  23. package/.agent-context/review-checklists/performance-audit.md +65 -0
  24. package/.agent-context/review-checklists/pr-checklist.md +97 -0
  25. package/.agent-context/review-checklists/release-operations.md +29 -0
  26. package/.agent-context/review-checklists/security-audit.md +113 -0
  27. package/.agent-context/rules/api-docs.md +186 -0
  28. package/.agent-context/rules/architecture.md +198 -0
  29. package/.agent-context/rules/database-design.md +202 -0
  30. package/.agent-context/rules/efficiency-vs-hype.md +143 -0
  31. package/.agent-context/rules/error-handling.md +234 -0
  32. package/.agent-context/rules/event-driven.md +226 -0
  33. package/.agent-context/rules/frontend-architecture.md +66 -0
  34. package/.agent-context/rules/git-workflow.md +200 -0
  35. package/.agent-context/rules/microservices.md +174 -0
  36. package/.agent-context/rules/naming-conv.md +141 -0
  37. package/.agent-context/rules/performance.md +168 -0
  38. package/.agent-context/rules/realtime.md +47 -0
  39. package/.agent-context/rules/security.md +195 -0
  40. package/.agent-context/rules/testing.md +178 -0
  41. package/.agent-context/stacks/csharp.md +149 -0
  42. package/.agent-context/stacks/go.md +181 -0
  43. package/.agent-context/stacks/java.md +135 -0
  44. package/.agent-context/stacks/php.md +178 -0
  45. package/.agent-context/stacks/python.md +153 -0
  46. package/.agent-context/stacks/ruby.md +80 -0
  47. package/.agent-context/stacks/rust.md +86 -0
  48. package/.agent-context/stacks/typescript.md +317 -0
  49. package/.agent-context/state/architecture-map.md +25 -0
  50. package/.agent-context/state/dependency-map.md +32 -0
  51. package/.agent-override.md +36 -0
  52. package/.agents/workflows/init-project.md +29 -0
  53. package/.agents/workflows/refactor.md +29 -0
  54. package/.agents/workflows/review-code.md +29 -0
  55. package/.cursorrules +140 -0
  56. package/.gemini/instructions.md +97 -0
  57. package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -0
  58. package/.github/copilot-instructions.md +104 -0
  59. package/.github/workflows/benchmark-detection.yml +38 -0
  60. package/.github/workflows/frontend-usability-gate.yml +36 -0
  61. package/.github/workflows/release-gate.yml +32 -0
  62. package/.github/workflows/sbom-compliance.yml +32 -0
  63. package/.windsurfrules +106 -0
  64. package/AGENTS.md +131 -0
  65. package/CONTRIBUTING.md +136 -0
  66. package/LICENSE +21 -0
  67. package/README.md +239 -0
  68. package/bin/agentic-senior-core.js +1147 -0
  69. package/mcp.json +29 -0
  70. package/package.json +50 -0
  71. package/scripts/detection-benchmark.mjs +138 -0
  72. package/scripts/frontend-usability-audit.mjs +87 -0
  73. package/scripts/generate-sbom.mjs +61 -0
  74. package/scripts/init-project.ps1 +105 -0
  75. package/scripts/init-project.sh +131 -0
  76. package/scripts/llm-judge.mjs +664 -0
  77. package/scripts/release-gate.mjs +116 -0
  78. package/scripts/validate.mjs +554 -0
@@ -0,0 +1,198 @@
1
+ # Architecture — Separation of Concerns & Structure
2
+
3
+ > If your service file imports an HTTP library, your architecture is broken.
4
+ > If your controller contains SQL, you've already lost.
5
+
6
+ ## The Core Principle
7
+
8
+ **Every layer has ONE job. Layer leaks are bugs — not "pragmatic shortcuts."**
9
+
10
+ ```
11
+ ┌─────────────────────────────────────────┐
12
+ │ TRANSPORT / CONTROLLER │ ← Parse input, validate shape, return response
13
+ │ (HTTP, CLI, WebSocket, Queue) │ ← NO business logic here. EVER.
14
+ ├─────────────────────────────────────────┤
15
+ │ APPLICATION / SERVICE │ ← Business rules, orchestration, transactions
16
+ │ (Use cases, workflows) │ ← NO HTTP, NO SQL, NO framework imports
17
+ ├─────────────────────────────────────────┤
18
+ │ DOMAIN / ENTITY │ ← Pure business objects, value objects
19
+ │ (Models, rules, calculations) │ ← ZERO external dependencies
20
+ ├─────────────────────────────────────────┤
21
+ │ INFRASTRUCTURE / REPOSITORY │ ← Database, external APIs, file system
22
+ │ (Data access, adapters) │ ← NO business logic
23
+ └─────────────────────────────────────────┘
24
+ ```
25
+
26
+ ## Layer Rules (Enforced)
27
+
28
+ ### Transport Layer (Controller / Handler / Route)
29
+ **Allowed:**
30
+ - Parse and validate incoming request (DTO/schema validation)
31
+ - Call application/service layer
32
+ - Format and return HTTP response (status code, headers)
33
+ - Handle authentication/authorization middleware
34
+
35
+ **BANNED:**
36
+ - Database queries or ORM calls
37
+ - Business logic (if/else on business rules)
38
+ - Direct calls to external APIs
39
+ - Transaction management
40
+
41
+ ### Application Layer (Service / Use Case)
42
+ **Allowed:**
43
+ - Orchestrate business operations
44
+ - Call repository layer for data
45
+ - Apply business rules and validations
46
+ - Manage transactions
47
+ - Emit domain events
48
+
49
+ **BANNED:**
50
+ - HTTP request/response objects
51
+ - Framework-specific decorators (keep framework coupling minimal)
52
+ - Direct SQL or raw database calls
53
+ - UI/presentation logic
54
+
55
+ ### Domain Layer (Entity / Value Object)
56
+ **Allowed:**
57
+ - Business calculations and rules
58
+ - Validation of domain invariants
59
+ - Type definitions and interfaces
60
+
61
+ **BANNED:**
62
+ - ANY external dependency (database, HTTP, framework)
63
+ - Side effects (logging, API calls, file I/O)
64
+ - Infrastructure concerns
65
+
66
+ ### Infrastructure Layer (Repository / Adapter)
67
+ **Allowed:**
68
+ - Database queries (SQL, ORM, document queries)
69
+ - External API calls (wrapped in adapters)
70
+ - File system operations
71
+ - Cache operations
72
+
73
+ **BANNED:**
74
+ - Business logic (no if/else on business rules in queries)
75
+ - HTTP response formatting
76
+ - Direct exposure to transport layer
77
+
78
+ ---
79
+
80
+ ## Dependency Direction
81
+
82
+ Dependencies flow **inward only**:
83
+
84
+ ```
85
+ Transport → Application → Domain ← Infrastructure
86
+
87
+ Infrastructure
88
+
89
+ NEVER: Domain → Infrastructure (use interfaces/ports)
90
+ NEVER: Application → Transport
91
+ NEVER: Infrastructure → Application (except through interfaces)
92
+ ```
93
+
94
+ The Domain layer depends on NOTHING. Everything depends on the Domain.
95
+
96
+ ---
97
+
98
+ ## Default Architecture: Modular Monolith
99
+
100
+ Start with a **Modular Monolith**. Do NOT start with microservices.
101
+
102
+ **Switch to microservices ONLY if 2+ of these triggers exist:**
103
+ 1. Frequent deploy conflicts across domains (teams blocking each other)
104
+ 2. Clear scale mismatch (one module needs 100x resources of another)
105
+ 3. Team ownership collision (multiple teams editing same module)
106
+ 4. Fault isolation requirement (one module crashing must not kill others)
107
+ 5. Stable contracts with clear data boundaries already exist
108
+
109
+ If these triggers don't exist, microservices are **premature complexity**.
110
+
111
+ ---
112
+
113
+ ## Project Structure: Feature-Based Grouping
114
+
115
+ ### ❌ BANNED: Technical Grouping
116
+ ```
117
+ src/
118
+ controllers/ ← 50 controllers in one flat folder?
119
+ userController.ts
120
+ orderController.ts
121
+ paymentController.ts
122
+ services/ ← Good luck finding related code
123
+ userService.ts
124
+ orderService.ts
125
+ repositories/
126
+ userRepository.ts
127
+ orderRepository.ts
128
+ ```
129
+
130
+ ### ✅ REQUIRED: Feature/Domain Grouping
131
+ ```
132
+ src/
133
+ modules/ ← Backend
134
+ user/
135
+ user.controller.ts ← Transport
136
+ user.service.ts ← Application
137
+ user.repository.ts ← Infrastructure
138
+ user.entity.ts ← Domain
139
+ user.dto.ts ← Data Transfer Objects
140
+ user.module.ts ← Module registration
141
+ __tests__/
142
+ user.service.test.ts
143
+ order/
144
+ order.controller.ts
145
+ order.service.ts
146
+ ...
147
+ shared/ ← Cross-cutting concerns
148
+ config/
149
+ errors/
150
+ logging/
151
+ middleware/
152
+
153
+ src/
154
+ features/ ← Frontend
155
+ payment/
156
+ api/ ← HTTP client + DTOs
157
+ hooks/ ← React hooks / state
158
+ components/ ← UI components
159
+ types/ ← Type definitions
160
+ utils/ ← Feature-specific utils
161
+ index.ts ← Public API barrel
162
+ components/
163
+ ui/ ← Shared UI primitives
164
+ layout/ ← Layout components
165
+ lib/ ← Shared utilities
166
+ config/ ← App configuration
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Module Communication
172
+
173
+ ### Within a Monolith
174
+ Modules communicate through **public interfaces only**:
175
+ ```
176
+ // ✅ CORRECT: Import from module's public API
177
+ import { UserService } from '@/modules/user';
178
+
179
+ // ❌ BANNED: Reach into another module's internals
180
+ import { UserRepository } from '@/modules/user/user.repository';
181
+ ```
182
+
183
+ ### Between Services (if microservices)
184
+ - Use well-defined contracts (REST, gRPC, events)
185
+ - Never share databases between services
186
+ - Define schemas at boundaries (Protobuf, JSON Schema, Zod)
187
+
188
+ ---
189
+
190
+ ## The Architecture Smell Test
191
+
192
+ Ask yourself these questions. If ANY answer is "yes", your architecture is broken:
193
+
194
+ 1. Can I change the database without touching business logic? (Must be YES)
195
+ 2. Can I switch from REST to GraphQL without rewriting services? (Must be YES)
196
+ 3. Can I test business logic without a running database? (Must be YES)
197
+ 4. Does each module have a clear, single responsibility? (Must be YES)
198
+ 5. Can a new developer find all related code in one directory? (Must be YES)
@@ -0,0 +1,202 @@
1
+ # Database Design — Schema Is Your Foundation
2
+
3
+ > A poorly designed schema is a bug factory.
4
+ > You can fix bad code in hours. A bad schema takes weeks.
5
+
6
+ ## Normalization Rules
7
+
8
+ ### Third Normal Form (3NF) is the Default
9
+
10
+ ```
11
+ ❌ BANNED: Flat tables with repeated data
12
+ Users:
13
+ | id | name | order_id | order_total | product_name |
14
+ | 1 | Jane | 101 | 99.99 | Widget |
15
+ | 1 | Jane | 102 | 49.99 | Gadget |
16
+ → name is duplicated, update anomalies guaranteed
17
+
18
+ ✅ REQUIRED: Normalized to 3NF
19
+ Users: | id | name | email |
20
+ Orders: | id | user_id | total | status |
21
+ Products: | id | name | price |
22
+ OrderItems: | order_id | product_id | quantity |
23
+ → Each fact is stored exactly once
24
+ ```
25
+
26
+ ### When to Denormalize
27
+
28
+ Denormalization is allowed ONLY with documented justification:
29
+
30
+ 1. **Read-heavy query** that joins 4+ tables and is called >1000x/sec
31
+ 2. **Reporting/analytics** where query speed matters more than write consistency
32
+ 3. **CQRS read model** that is purpose-built for a specific query
33
+
34
+ ```
35
+ REQUIRED for every denormalization:
36
+ - Document WHY (link to performance evidence)
37
+ - Document HOW it stays in sync (trigger, event, scheduled job)
38
+ - Add a comment in the schema: "Denormalized for [query name], synced by [mechanism]"
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Indexing Strategy
44
+
45
+ ### Rules of Indexing
46
+
47
+ 1. **Every foreign key gets an index** — joins on unindexed FKs are full table scans
48
+ 2. **Every WHERE clause in a frequent query gets evaluated** — if the column appears in WHERE and the table has >10K rows, consider an index
49
+ 3. **Composite indexes matter** — `INDEX(status, created_at)` ≠ `INDEX(created_at, status)`. Column order follows the query pattern (most selective first, or matching WHERE + ORDER BY)
50
+ 4. **Covering indexes** — include frequently selected columns to avoid table lookups
51
+
52
+ ### What to Index
53
+
54
+ | Pattern | Index Type | Example |
55
+ |---------|-----------|---------|
56
+ | FK lookups | B-tree (default) | `orders.user_id` |
57
+ | Status + date filters | Composite | `INDEX(status, created_at)` |
58
+ | Full-text search | Full-text / GIN | `products.description` |
59
+ | JSON queries | GIN (PostgreSQL) | `metadata->>'type'` |
60
+ | Unique constraints | Unique | `users.email` |
61
+ | Geospatial | Spatial / GiST | `locations.coordinates` |
62
+
63
+ ### What NOT to Index
64
+
65
+ - Columns with very low cardinality on small tables (`is_active` with 2 values on 100 rows)
66
+ - Tables with <1000 rows (index overhead > benefit)
67
+ - Write-heavy tables where every INSERT updates 10+ indexes
68
+ - Columns never used in WHERE, JOIN, or ORDER BY
69
+
70
+ ### Index Monitoring
71
+
72
+ ```
73
+ REQUIRED:
74
+ - Identify unused indexes monthly → DROP them (they slow writes)
75
+ - Identify missing indexes → EXPLAIN ANALYZE on slow queries
76
+ - Track index size vs table size → alarming if indexes > 3x table size
77
+ ```
78
+
79
+ ---
80
+
81
+ ## Migration Standards
82
+
83
+ ### Rules
84
+
85
+ 1. **Every schema change is a migration** — never modify production schemas manually
86
+ 2. **Migrations are versioned and sequential** — `001_create_users.sql`, `002_add_email_index.sql`
87
+ 3. **Migrations are idempotent** — running twice produces the same result
88
+ 4. **Migrations are reversible** — every UP has a DOWN (or document why rollback is impossible)
89
+ 5. **Migrations run in CI** — test against a real database, not just syntax checks
90
+
91
+ ### Safe Migration Patterns
92
+
93
+ ```
94
+ ✅ SAFE (no downtime):
95
+ 1. ADD COLUMN with default (nullable or with DEFAULT)
96
+ 2. CREATE INDEX CONCURRENTLY
97
+ 3. ADD new table
98
+ 4. Rename via view + synonym (transitional)
99
+
100
+ ❌ DANGEROUS (requires planned downtime or careful orchestration):
101
+ 1. DROP COLUMN (deploy code changes removing column usage FIRST)
102
+ 2. RENAME COLUMN (use gradual rename: add new → copy data → remove old)
103
+ 3. ALTER COLUMN TYPE (may lock table on large datasets)
104
+ 4. DROP TABLE (ensure no code references remain)
105
+ ```
106
+
107
+ ### The Expand-Contract Pattern
108
+
109
+ For breaking schema changes in zero-downtime deployments:
110
+
111
+ ```
112
+ Phase 1 (Expand): Add new column/table alongside old one
113
+ → Code writes to BOTH old and new
114
+ Phase 2 (Migrate): Backfill data from old to new
115
+ → Verify data consistency
116
+ Phase 3 (Contract): Remove old column/table
117
+ → Code reads/writes only new
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Data Type Selection
123
+
124
+ ### Use the Right Type
125
+
126
+ | Data | ❌ Wrong | ✅ Right | Why |
127
+ |------|---------|---------|-----|
128
+ | Money | `FLOAT` | `DECIMAL(19,4)` or integer cents | Floating point arithmetic is imprecise |
129
+ | UUID | `VARCHAR(36)` | `UUID` native type | 16 bytes vs 36 bytes, indexing is faster |
130
+ | Timestamps | `VARCHAR` | `TIMESTAMPTZ` | Timezone-aware, sortable, comparable |
131
+ | IP addresses | `VARCHAR(45)` | `INET` (PostgreSQL) | Validation built-in, range queries |
132
+ | Boolean | `INT` (0/1) | `BOOLEAN` | Semantic clarity |
133
+ | Enums | `VARCHAR` | Database ENUM or CHECK constraint | Prevents invalid values |
134
+ | JSON blobs | `TEXT` | `JSONB` (PostgreSQL) | Indexable, queryable, validated |
135
+
136
+ ### Column Naming
137
+
138
+ ```
139
+ ✅ REQUIRED:
140
+ - snake_case for all column names
141
+ - Descriptive: created_at, updated_at, deleted_at (not ts, mod, del)
142
+ - Foreign keys: {referenced_table_singular}_id (e.g., user_id, order_id)
143
+ - Boolean columns: is_active, has_verified_email, can_edit
144
+ - Timestamps: {verb}_at (created_at, verified_at, shipped_at)
145
+ - Amounts: {noun}_amount or {noun}_cents (total_amount, tax_cents)
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Query Design Rules
151
+
152
+ ### Pagination (Mandatory for Lists)
153
+
154
+ ```
155
+ ❌ BANNED:
156
+ SELECT * FROM orders;
157
+ -- Returns 2 million rows, OOM crash
158
+
159
+ ✅ REQUIRED: Offset pagination (simple, okay for < 100K rows)
160
+ SELECT * FROM orders ORDER BY id LIMIT 20 OFFSET 40;
161
+
162
+ ✅ PREFERRED: Cursor pagination (performant at any scale)
163
+ SELECT * FROM orders WHERE id > :last_seen_id ORDER BY id LIMIT 20;
164
+ ```
165
+
166
+ **Rule:** Use cursor-based pagination for tables > 100K rows. Offset pagination degrades linearly with OFFSET value.
167
+
168
+ ### Soft Deletes vs Hard Deletes
169
+
170
+ ```
171
+ Use soft deletes (deleted_at column) when:
172
+ - Legal/compliance requires data retention
173
+ - Users might want to "undelete"
174
+ - Related data would break without the parent record
175
+
176
+ Use hard deletes when:
177
+ - GDPR/privacy requires actual data removal
178
+ - Data has no business value after deletion
179
+ - Storage cost of keeping data outweighs benefit
180
+
181
+ If soft deleting:
182
+ - Add deleted_at to ALL queries: WHERE deleted_at IS NULL
183
+ - Add a partial index: WHERE deleted_at IS NULL (for performance)
184
+ - Schedule periodic hard-delete of old soft-deleted records
185
+ ```
186
+
187
+ ---
188
+
189
+ ## The Database Design Checklist
190
+
191
+ Before any schema goes to production:
192
+
193
+ - [ ] Schema is normalized to 3NF (denormalization documented if present)
194
+ - [ ] All foreign keys have indexes
195
+ - [ ] Primary keys use appropriate type (UUID or BIGINT)
196
+ - [ ] Timestamps use TIMESTAMPTZ (not VARCHAR)
197
+ - [ ] Money uses DECIMAL or integer cents (never FLOAT)
198
+ - [ ] Migration is versioned, reversible, and tested in CI
199
+ - [ ] All list queries have LIMIT (pagination implemented)
200
+ - [ ] Indexes justified with EXPLAIN ANALYZE on expected queries
201
+ - [ ] Column naming follows convention (snake_case, descriptive)
202
+ - [ ] Soft delete vs hard delete decision documented
@@ -0,0 +1,143 @@
1
+ # Efficiency vs. Hype — Choose Stable, Not Shiny
2
+
3
+ > Every dependency is a liability. Every `npm install` is a trust decision.
4
+ > The best dependency is the one you don't need.
5
+
6
+ ## The Dependency Decision Framework
7
+
8
+ Before adding ANY dependency, answer these 5 questions:
9
+
10
+ ### 1. Can You Do It Without a Library? (The stdlib-first Rule)
11
+ ```
12
+ ❌ OVER-ENGINEERING:
13
+ npm install is-odd # 1 line of code: n % 2 !== 0
14
+ npm install left-pad # Already in String.prototype.padStart
15
+ npm install is-number # typeof x === 'number' && !isNaN(x)
16
+ npm install array-flatten # Array.prototype.flat() exists since ES2019
17
+
18
+ ✅ USE THE LANGUAGE:
19
+ const isOdd = (n: number) => n % 2 !== 0;
20
+ const padded = str.padStart(10, '0');
21
+ const flat = nested.flat(Infinity);
22
+ ```
23
+
24
+ **Dependency Defense:** If the user asks to install a new library, or if you feel the need to use one, evaluate it against the "stdlib-first" rule. If the functionality can be implemented safely in under 20 lines of code, write it yourself. If a dependency is strictly necessary, you MUST justify it by providing its bundle size, maintenance status, and why the standard library is insufficient.
25
+
26
+ ### 2. Is It Maintained? (The Pulse Check)
27
+ | Signal | 🟢 Healthy | 🔴 Dead |
28
+ |--------|-----------|---------|
29
+ | Last commit | < 6 months ago | > 2 years ago |
30
+ | Open issues | Actively triaged | 500+ unread |
31
+ | Downloads/week | Growing or stable | Declining |
32
+ | Bus factor | > 3 maintainers | 1 maintainer, inactive |
33
+ | Security | No known CVEs | Unpatched vulnerabilities |
34
+
35
+ **Rule:** If a library has a bus factor of 1 and no commit in 12+ months, it is a risk. Find an alternative or vendor-fork it.
36
+
37
+ ### 3. What's the Cost? (The Weight Check)
38
+ ```
39
+ Before: npm install moment # 289KB minified, entire library for date formatting
40
+ After: npm install date-fns # 12KB for just the functions you use (tree-shakeable)
41
+ Better: Intl.DateTimeFormat # 0KB — built into the runtime
42
+ ```
43
+
44
+ **Rule:** Check the bundle impact. Use [bundlephobia.com](https://bundlephobia.com) for JS packages. If a library adds > 50KB to your bundle for a simple feature, find a lighter alternative or implement it yourself.
45
+
46
+ ### 4. Is It the Community Standard? (The Ecosystem Rule)
47
+ Prefer packages that the ecosystem has settled on:
48
+
49
+ | Need | ✅ Standard | ❌ Avoid |
50
+ |------|-----------|---------|
51
+ | HTTP client (Node) | `undici` (built-in) / native `fetch` / `ky` | `axios` (declining, CVE-2025-58754, bloated) |
52
+ | Validation | `zod` | `joi` (heavier), `yup` (less type-safe) |
53
+ | ORM (Node) | `prisma`, `drizzle` | `sequelize` (legacy API), `typeorm` (decorator hell) |
54
+ | Date handling | `date-fns`, `dayjs`, `Temporal` (when stable) | `moment` (deprecated, massive) |
55
+ | Testing | `vitest` (new projects), `jest` (existing) | `mocha` + `chai` + `sinon` (3 deps for what 1 does) |
56
+ | Password hashing | `argon2` (OWASP primary), `bcrypt` (legacy) | Custom crypto (NEVER) |
57
+ | Env loading | `dotenv` (if needed) | Custom `.env` parser |
58
+
59
+ **Note:** These are current recommendations as of March 2026. Evaluate against this framework; don't blindly follow.
60
+
61
+ ### 5. Can You Remove It Later? (The Exit Strategy)
62
+ ```
63
+ ❌ HIGH LOCK-IN:
64
+ // Decorators from a specific framework scattered across 200 files
65
+ @Controller() @Injectable() @Guard() // In every file — framework is your entire architecture
66
+
67
+ ✅ LOW LOCK-IN:
68
+ // Framework stays at the edges; business logic is framework-free
69
+ // Switching from Express to Fastify only changes the transport layer
70
+ ```
71
+
72
+ **Rule:** Wrap external dependencies that touch > 5 files. If you need to replace a library, it should only affect the wrapper, not your entire codebase.
73
+
74
+ ---
75
+
76
+ ## The Hype Trap (AI-Generated Code Alert)
77
+
78
+ AI agents love suggesting trendy libraries because they appear frequently in training data. Watch for:
79
+
80
+ ### Red Flags
81
+ 1. **"Just install X"** without explaining why → ASK: Can I do this with the stdlib?
82
+ 2. **Library does one thing** that's 5 lines of code → REJECT: Write it yourself
83
+ 3. **Library is in alpha/beta** with < 1 year of releases → REJECT: Not production-ready
84
+ 4. **Library has a cooler API** but the current one works fine → REJECT: "Cool" is not a business requirement
85
+ 5. **"Everyone is using it"** → SO WHAT: Popularity is not a quality signal
86
+
87
+ ### The Agent Must Justify Dependencies
88
+ When an AI agent suggests adding a new dependency, it MUST provide:
89
+ ```
90
+ 📦 DEPENDENCY JUSTIFICATION
91
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━
92
+ Package: [name@version]
93
+ Purpose: [what it does in 1 sentence]
94
+ Stdlib Alternative: [why it's insufficient — or "none"]
95
+ Bundle Size: [minified + gzipped]
96
+ Maintenance: [last release date, maintainer count]
97
+ Lock-in Risk: [low/medium/high — how many files would it touch]
98
+ Exit Strategy: [how to remove it if needed]
99
+ ```
100
+
101
+ ---
102
+
103
+ ## Dependency Update Strategy
104
+
105
+ 1. **Pin exact versions** in lockfiles (already default with package-lock.json, bun.lockb)
106
+ 2. **Review changelogs** before major updates — never blindly `npm update`
107
+ 3. **Update in isolation** — one dependency per PR, with tests passing
108
+ 4. **Security patches immediately** — don't wait for the sprint
109
+ 5. **Monthly audit** — run `npm audit` / `bun audit` and address findings
110
+
111
+ ---
112
+
113
+ ## The Zero-Dependency Ideal
114
+
115
+ The best packages are those with zero or minimal dependencies themselves:
116
+ - `zod` — 0 dependencies ✅
117
+ - `date-fns` — 0 dependencies ✅
118
+ - `nanoid` — 0 dependencies ✅
119
+ - `bcrypt` — 1 native dependency (justified for crypto) ✅
120
+
121
+ A package that pulls in 50 transitive dependencies for a simple feature is a supply chain attack waiting to happen.
122
+
123
+ ---
124
+
125
+ ## Quick Decision Tree
126
+
127
+ ```
128
+ Do I need this functionality?
129
+ → No → Don't install anything
130
+ → Yes ↓
131
+
132
+ Can I write it in < 20 lines?
133
+ → Yes → Write it yourself
134
+ → No ↓
135
+
136
+ Does the language/runtime provide it?
137
+ → Yes → Use the built-in
138
+ → No ↓
139
+
140
+ Is there a well-maintained, lightweight, community-standard package?
141
+ → Yes → Install it, add justification comment
142
+ → No → Build a minimal internal implementation, consider vendoring
143
+ ```