agentic-team-templates 0.9.1 → 0.10.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agentic-team-templates",
3
- "version": "0.9.1",
3
+ "version": "0.10.0",
4
4
  "description": "AI coding assistant templates for Cursor IDE. Pre-configured rules and guidelines that help AI assistants write better code. - use at your own risk",
5
5
  "keywords": [
6
6
  "cursor",
package/src/index.js CHANGED
@@ -28,6 +28,14 @@ const TEMPLATES = {
28
28
  description: 'Command-line applications and developer tools (Cobra, Commander, Click)',
29
29
  rules: ['architecture.md', 'arguments.md', 'distribution.md', 'error-handling.md', 'overview.md', 'testing.md', 'user-experience.md']
30
30
  },
31
+ 'data-engineering': {
32
+ description: 'Data platforms and pipelines (ETL, data modeling, data quality)',
33
+ rules: ['data-modeling.md', 'data-quality.md', 'overview.md', 'performance.md', 'pipeline-design.md', 'security.md', 'testing.md']
34
+ },
35
+ 'devops-sre': {
36
+ description: 'DevOps and SRE practices (incident management, observability, SLOs, chaos engineering)',
37
+ rules: ['capacity-planning.md', 'change-management.md', 'chaos-engineering.md', 'disaster-recovery.md', 'incident-management.md', 'observability.md', 'overview.md', 'postmortems.md', 'runbooks.md', 'slo-sli.md', 'toil-reduction.md']
38
+ },
31
39
  'documentation': {
32
40
  description: 'Technical documentation standards (READMEs, API docs, ADRs, code comments)',
33
41
  rules: ['adr.md', 'api-documentation.md', 'code-comments.md', 'maintenance.md', 'overview.md', 'readme-standards.md']
@@ -36,10 +44,34 @@ const TEMPLATES = {
36
44
  description: 'Full-stack web applications (Next.js, Nuxt, SvelteKit, Remix)',
37
45
  rules: ['api-contracts.md', 'architecture.md', 'overview.md', 'shared-types.md', 'testing.md']
38
46
  },
47
+ 'javascript-expert': {
48
+ description: 'Principal-level JavaScript engineering across Node.js, React, vanilla JS, and testing',
49
+ rules: ['language-deep-dive.md', 'node-patterns.md', 'overview.md', 'performance.md', 'react-patterns.md', 'testing.md', 'tooling.md']
50
+ },
51
+ 'ml-ai': {
52
+ description: 'Machine learning and AI systems (model development, deployment, monitoring)',
53
+ rules: ['data-engineering.md', 'deployment.md', 'model-development.md', 'monitoring.md', 'overview.md', 'security.md', 'testing.md']
54
+ },
39
55
  'mobile': {
40
56
  description: 'Mobile applications (React Native, Flutter, native iOS/Android)',
41
57
  rules: ['navigation.md', 'offline-first.md', 'overview.md', 'performance.md', 'testing.md']
42
58
  },
59
+ 'platform-engineering': {
60
+ description: 'Internal developer platforms, infrastructure automation, and reliability engineering',
61
+ rules: ['ci-cd.md', 'developer-experience.md', 'infrastructure-as-code.md', 'kubernetes.md', 'observability.md', 'overview.md', 'security.md', 'testing.md']
62
+ },
63
+ 'product-manager': {
64
+ description: 'Product management with customer-centric discovery, prioritization, and execution',
65
+ rules: ['communication.md', 'discovery.md', 'metrics.md', 'overview.md', 'prioritization.md', 'requirements.md']
66
+ },
67
+ 'qa-engineering': {
68
+ description: 'Quality assurance programs for confident, rapid software delivery',
69
+ rules: ['automation.md', 'metrics.md', 'overview.md', 'quality-gates.md', 'test-design.md', 'test-strategy.md']
70
+ },
71
+ 'testing': {
72
+ description: 'Comprehensive testing practices (TDD, test design, CI/CD integration, performance testing)',
73
+ rules: ['advanced-techniques.md', 'ci-cd-integration.md', 'overview.md', 'performance-testing.md', 'quality-metrics.md', 'reliability.md', 'tdd-methodology.md', 'test-data.md', 'test-design.md', 'test-types.md']
74
+ },
43
75
  'utility-agent': {
44
76
  description: 'AI agent utilities with context management and hallucination prevention',
45
77
  rules: ['action-control.md', 'context-management.md', 'hallucination-prevention.md', 'overview.md', 'token-optimization.md']
package/src/index.test.js CHANGED
@@ -75,9 +75,17 @@ describe('Constants', () => {
75
75
  const expectedTemplates = [
76
76
  'blockchain',
77
77
  'cli-tools',
78
+ 'data-engineering',
79
+ 'devops-sre',
78
80
  'documentation',
79
81
  'fullstack',
82
+ 'javascript-expert',
83
+ 'ml-ai',
80
84
  'mobile',
85
+ 'platform-engineering',
86
+ 'product-manager',
87
+ 'qa-engineering',
88
+ 'testing',
81
89
  'utility-agent',
82
90
  'web-backend',
83
91
  'web-frontend',
@@ -0,0 +1,245 @@
1
+ # JavaScript Language Deep Dive
2
+
3
+ Advanced JavaScript patterns and idioms for expert-level engineering.
4
+
5
+ ## The Event Loop
6
+
7
+ Understanding execution order is fundamental:
8
+
9
+ ```typescript
10
+ // Know the execution order: synchronous > microtasks > macrotasks
11
+ console.log('1 - sync');
12
+
13
+ setTimeout(() => console.log('2 - macrotask'), 0);
14
+
15
+ Promise.resolve().then(() => console.log('3 - microtask'));
16
+
17
+ queueMicrotask(() => console.log('4 - microtask'));
18
+
19
+ console.log('5 - sync');
20
+
21
+ // Output: 1, 5, 3, 4, 2
22
+ ```
23
+
24
+ ### Async Patterns
25
+
26
+ ```typescript
27
+ // Prefer async/await over raw promises
28
+ // But know when Promise combinators are the right tool
29
+
30
+ // Parallel independent operations
31
+ const [users, posts] = await Promise.all([
32
+ fetchUsers(),
33
+ fetchPosts(),
34
+ ]);
35
+
36
+ // Race with timeout
37
+ const withTimeout = <T>(promise: Promise<T>, ms: number): Promise<T> =>
38
+ Promise.race([
39
+ promise,
40
+ new Promise<never>((_, reject) =>
41
+ setTimeout(() => reject(new Error(`Timeout after ${ms}ms`)), ms)
42
+ ),
43
+ ]);
44
+
45
+ // Settle all, handle individually
46
+ const results = await Promise.allSettled(tasks.map(processTask));
47
+ const failures = results.filter(
48
+ (r): r is PromiseRejectedResult => r.status === 'rejected'
49
+ );
50
+
51
+ // Async iteration for streams
52
+ async function* readChunks(stream: ReadableStream<Uint8Array>) {
53
+ const reader = stream.getReader();
54
+ try {
55
+ while (true) {
56
+ const { done, value } = await reader.read();
57
+ if (done) break;
58
+ yield value;
59
+ }
60
+ } finally {
61
+ reader.releaseLock();
62
+ }
63
+ }
64
+ ```
65
+
66
+ ## Closures and Scope
67
+
68
+ ```typescript
69
+ // Closures for encapsulation
70
+ const createRateLimiter = (maxCalls: number, windowMs: number) => {
71
+ const calls: number[] = [];
72
+
73
+ return <T>(fn: () => T): T | null => {
74
+ const now = Date.now();
75
+ const windowStart = now - windowMs;
76
+ // Remove expired entries
77
+ while (calls.length > 0 && calls[0]! < windowStart) calls.shift();
78
+
79
+ if (calls.length >= maxCalls) return null;
80
+ calls.push(now);
81
+ return fn();
82
+ };
83
+ };
84
+
85
+ // Private state with closures (pre-#private fields pattern)
86
+ // Prefer #private fields in classes, closures in functions
87
+ ```
88
+
89
+ ## Proxy and Reflect
90
+
91
+ ```typescript
92
+ // Observable objects
93
+ const createObservable = <T extends object>(
94
+ target: T,
95
+ onChange: (prop: string | symbol, value: unknown) => void,
96
+ ): T =>
97
+ new Proxy(target, {
98
+ set(obj, prop, value, receiver) {
99
+ const result = Reflect.set(obj, prop, value, receiver);
100
+ onChange(prop, value);
101
+ return result;
102
+ },
103
+ });
104
+
105
+ // Validation proxies
106
+ const createValidated = <T extends Record<string, unknown>>(
107
+ target: T,
108
+ validators: Partial<Record<keyof T, (v: unknown) => boolean>>,
109
+ ): T =>
110
+ new Proxy(target, {
111
+ set(obj, prop, value, receiver) {
112
+ const validate = validators[prop as keyof T];
113
+ if (validate && !validate(value)) {
114
+ throw new TypeError(`Invalid value for ${String(prop)}`);
115
+ }
116
+ return Reflect.set(obj, prop, value, receiver);
117
+ },
118
+ });
119
+ ```
120
+
121
+ ## WeakRef and FinalizationRegistry
122
+
123
+ ```typescript
124
+ // Cache that doesn't prevent garbage collection
125
+ class WeakCache<K extends object, V> {
126
+ readonly #cache = new Map<string, WeakRef<V & object>>();
127
+ readonly #registry = new FinalizationRegistry<string>((key) => {
128
+ this.#cache.delete(key);
129
+ });
130
+
131
+ set(key: string, value: V & object): void {
132
+ this.#cache.set(key, new WeakRef(value));
133
+ this.#registry.register(value, key);
134
+ }
135
+
136
+ get(key: string): V | undefined {
137
+ return this.#cache.get(key)?.deref();
138
+ }
139
+ }
140
+ ```
141
+
142
+ ## Iterators and Generators
143
+
144
+ ```typescript
145
+ // Custom iterable
146
+ class Range implements Iterable<number> {
147
+ constructor(
148
+ private readonly start: number,
149
+ private readonly end: number,
150
+ private readonly step = 1,
151
+ ) {}
152
+
153
+ *[Symbol.iterator](): Generator<number> {
154
+ for (let i = this.start; i < this.end; i += this.step) {
155
+ yield i;
156
+ }
157
+ }
158
+ }
159
+
160
+ // Lazy evaluation with generators
161
+ function* filter<T>(iterable: Iterable<T>, predicate: (item: T) => boolean) {
162
+ for (const item of iterable) {
163
+ if (predicate(item)) yield item;
164
+ }
165
+ }
166
+
167
+ function* map<T, U>(iterable: Iterable<T>, transform: (item: T) => U) {
168
+ for (const item of iterable) {
169
+ yield transform(item);
170
+ }
171
+ }
172
+
173
+ function* take<T>(iterable: Iterable<T>, count: number) {
174
+ let i = 0;
175
+ for (const item of iterable) {
176
+ if (i++ >= count) break;
177
+ yield item;
178
+ }
179
+ }
180
+
181
+ // Compose lazy operations — no intermediate arrays
182
+ const result = [...take(
183
+ map(
184
+ filter(hugeDataset, item => item.active),
185
+ item => item.name,
186
+ ),
187
+ 10,
188
+ )];
189
+ ```
190
+
191
+ ## Structured Clone and Transfer
192
+
193
+ ```typescript
194
+ // Deep clone without JSON.parse(JSON.stringify(...))
195
+ const clone = structuredClone(complexObject);
196
+
197
+ // Transfer ownership (zero-copy for ArrayBuffers)
198
+ const buffer = new ArrayBuffer(1024);
199
+ worker.postMessage({ buffer }, [buffer]);
200
+ // buffer.byteLength is now 0 — ownership transferred
201
+ ```
202
+
203
+ ## Module Patterns
204
+
205
+ ```typescript
206
+ // Named exports for tree-shaking
207
+ export const validateEmail = (email: string): boolean => { ... };
208
+ export const validatePhone = (phone: string): boolean => { ... };
209
+
210
+ // Barrel files only at package boundaries, never internal
211
+ // src/validators/index.ts — public API
212
+ export { validateEmail } from './email.js';
213
+ export { validatePhone } from './phone.js';
214
+
215
+ // Dynamic imports for code splitting
216
+ const module = await import(`./locales/${locale}.js`);
217
+
218
+ // Import attributes (for JSON, CSS modules)
219
+ import config from './config.json' with { type: 'json' };
220
+ ```
221
+
222
+ ## Anti-Patterns to Avoid
223
+
224
+ ```typescript
225
+ // Never: for...in on arrays (iterates prototype chain)
226
+ for (const key in array) { } // BAD
227
+
228
+ // Instead: for...of, .forEach, .map, .reduce
229
+ for (const item of array) { } // GOOD
230
+
231
+ // Never: == for comparison (type coercion surprises)
232
+ if (value == null) { } // Only acceptable case (null + undefined check)
233
+
234
+ // Never: delete on arrays (creates sparse array)
235
+ delete arr[2]; // BAD — leaves hole
236
+ arr.splice(2, 1); // GOOD
237
+
238
+ // Never: blocking the event loop
239
+ // Use worker_threads for CPU-intensive work in Node.js
240
+ // Use Web Workers in the browser
241
+
242
+ // Never: implicit globals
243
+ function bad() { x = 5; } // Creates global!
244
+ // Always use const/let, always use strict mode
245
+ ```
@@ -0,0 +1,184 @@
1
+ # Node.js Patterns
2
+
3
+ Expert-level Node.js patterns for building production services, CLIs, and tooling.
4
+
5
+ ## Runtime Essentials
6
+
7
+ ### Process Lifecycle
8
+
9
+ ```typescript
10
+ // Graceful shutdown
11
+ const shutdown = async (signal: string) => {
12
+ console.log(`Received ${signal}, shutting down gracefully...`);
13
+ server.close();
14
+ await db.disconnect();
15
+ process.exit(0);
16
+ };
17
+
18
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
19
+ process.on('SIGINT', () => shutdown('SIGINT'));
20
+
21
+ // Unhandled rejection = crash (don't swallow errors)
22
+ process.on('unhandledRejection', (reason) => {
23
+ console.error('Unhandled rejection:', reason);
24
+ process.exit(1);
25
+ });
26
+ ```
27
+
28
+ ### Streams
29
+
30
+ ```typescript
31
+ import { pipeline } from 'node:stream/promises';
32
+ import { createReadStream, createWriteStream } from 'node:fs';
33
+ import { createGzip } from 'node:zlib';
34
+ import { Transform } from 'node:stream';
35
+
36
+ // Always use pipeline for proper error handling and cleanup
37
+ await pipeline(
38
+ createReadStream('input.log'),
39
+ new Transform({
40
+ transform(chunk, _encoding, callback) {
41
+ const filtered = chunk
42
+ .toString()
43
+ .split('\n')
44
+ .filter((line: string) => line.includes('ERROR'))
45
+ .join('\n');
46
+ callback(null, filtered);
47
+ },
48
+ }),
49
+ createGzip(),
50
+ createWriteStream('errors.log.gz'),
51
+ );
52
+
53
+ // Web-standard streams in Node.js
54
+ const response = await fetch(url);
55
+ const reader = response.body!.getReader();
56
+ ```
57
+
58
+ ### Worker Threads
59
+
60
+ ```typescript
61
+ import { Worker, isMainThread, parentPort, workerData } from 'node:worker_threads';
62
+
63
+ if (isMainThread) {
64
+ const runWorker = <T>(data: unknown): Promise<T> =>
65
+ new Promise((resolve, reject) => {
66
+ const worker = new Worker(new URL(import.meta.url), { workerData: data });
67
+ worker.on('message', resolve);
68
+ worker.on('error', reject);
69
+ });
70
+
71
+ const result = await runWorker({ task: 'hash', input: largeBuffer });
72
+ } else {
73
+ // Worker thread — CPU-intensive work here
74
+ const result = performExpensiveComputation(workerData);
75
+ parentPort!.postMessage(result);
76
+ }
77
+ ```
78
+
79
+ ### File System
80
+
81
+ ```typescript
82
+ import { readFile, writeFile, mkdir, access } from 'node:fs/promises';
83
+ import { constants } from 'node:fs';
84
+
85
+ // Always use fs/promises, never sync variants in async code
86
+ const data = await readFile('config.json', 'utf-8');
87
+
88
+ // Check existence without TOCTOU race
89
+ const fileExists = async (path: string): Promise<boolean> => {
90
+ try {
91
+ await access(path, constants.F_OK);
92
+ return true;
93
+ } catch {
94
+ return false;
95
+ }
96
+ };
97
+
98
+ // Atomic writes to prevent corruption
99
+ import { writeFile as atomicWrite } from 'atomically';
100
+ await atomicWrite('important.json', JSON.stringify(data));
101
+
102
+ // Use node:path for all path manipulation
103
+ import { join, resolve, extname, basename } from 'node:path';
104
+ ```
105
+
106
+ ## Module System
107
+
108
+ ```typescript
109
+ // Use node: protocol for builtins (explicit, no ambiguity)
110
+ import { readFile } from 'node:fs/promises';
111
+ import { join } from 'node:path';
112
+ import { createHash } from 'node:crypto';
113
+
114
+ // ESM by default — set "type": "module" in package.json
115
+ // Use .js extensions in imports (required for ESM)
116
+ import { validate } from './validators.js';
117
+ ```
118
+
119
+ ## Error Handling in Node.js
120
+
121
+ ```typescript
122
+ // Custom error classes with cause chaining
123
+ class DatabaseError extends Error {
124
+ constructor(message: string, options?: ErrorOptions) {
125
+ super(message, options);
126
+ this.name = 'DatabaseError';
127
+ }
128
+ }
129
+
130
+ // Wrap external errors with context
131
+ try {
132
+ await db.query(sql);
133
+ } catch (err) {
134
+ throw new DatabaseError(`Query failed: ${sql}`, { cause: err });
135
+ }
136
+
137
+ // AbortController for cancellation
138
+ const controller = new AbortController();
139
+ setTimeout(() => controller.abort(), 5000);
140
+
141
+ try {
142
+ const response = await fetch(url, { signal: controller.signal });
143
+ } catch (err) {
144
+ if (err instanceof DOMException && err.name === 'AbortError') {
145
+ // Handle timeout specifically
146
+ }
147
+ throw err;
148
+ }
149
+ ```
150
+
151
+ ## Configuration
152
+
153
+ ```typescript
154
+ // Validate environment at startup, fail fast
155
+ import { z } from 'zod';
156
+
157
+ const EnvSchema = z.object({
158
+ NODE_ENV: z.enum(['development', 'production', 'test']),
159
+ PORT: z.coerce.number().int().positive().default(3000),
160
+ DATABASE_URL: z.string().url(),
161
+ API_KEY: z.string().min(1),
162
+ });
163
+
164
+ // Parse once at startup — crash if invalid
165
+ export const env = EnvSchema.parse(process.env);
166
+ ```
167
+
168
+ ## Anti-Patterns
169
+
170
+ ```typescript
171
+ // Never: require() in ESM (use import or createRequire)
172
+ // Never: sync fs operations in request handlers
173
+ // Never: unbounded concurrency
174
+ // Bad:
175
+ await Promise.all(thousandItems.map(item => processItem(item)));
176
+ // Good: Use p-limit or manual batching
177
+ import pLimit from 'p-limit';
178
+ const limit = pLimit(10);
179
+ await Promise.all(thousandItems.map(item => limit(() => processItem(item))));
180
+
181
+ // Never: string concatenation for SQL (injection risk)
182
+ // Never: eval() or new Function() with user input
183
+ // Never: process.exit() without cleanup
184
+ ```
@@ -0,0 +1,130 @@
1
+ # JavaScript Expert
2
+
3
+ Guidelines for principal-level JavaScript engineering across all runtimes, frameworks, and paradigms.
4
+
5
+ ## Scope
6
+
7
+ This ruleset applies to:
8
+ - Node.js services, CLIs, and tooling
9
+ - React, Vue, Angular, Svelte, and other UI frameworks
10
+ - Vanilla JavaScript and Web APIs
11
+ - TypeScript (strict mode, always)
12
+ - Build tools, bundlers, and transpilers
13
+ - Testing at every level (unit, integration, E2E, performance)
14
+
15
+ ## Core Philosophy
16
+
17
+ JavaScript is the runtime. Know it deeply:
18
+ - The event loop is not optional knowledge — it's the foundation
19
+ - Prototypes, closures, and the module system are first principles
20
+ - The spec (ECMAScript) is the source of truth, not blog posts
21
+ - Every abstraction leaks — understand what's underneath
22
+
23
+ ## Key Principles
24
+
25
+ ### 1. Language Mastery Over Framework Dependence
26
+
27
+ Frameworks come and go. JavaScript fundamentals are permanent:
28
+ - Understand `this` binding rules (default, implicit, explicit, `new`)
29
+ - Know the difference between the task queue, microtask queue, and rendering pipeline
30
+ - Use native APIs before reaching for libraries (`structuredClone`, `AbortController`, `Intl`, `URL`, `crypto.subtle`)
31
+ - Understand generator functions, iterators, and async iteration
32
+
33
+ ### 2. Type Safety Is Non-Negotiable
34
+
35
+ ```typescript
36
+ // Always: strict TypeScript
37
+ // tsconfig.json: "strict": true, "noUncheckedIndexedAccess": true
38
+
39
+ // Prefer discriminated unions over optional fields
40
+ type Result<T, E = Error> =
41
+ | { ok: true; value: T }
42
+ | { ok: false; error: E };
43
+
44
+ // Use const assertions and template literal types
45
+ const EVENTS = ['click', 'keydown', 'submit'] as const;
46
+ type EventName = (typeof EVENTS)[number];
47
+
48
+ // Branded types for domain safety
49
+ type UserId = string & { readonly __brand: unique symbol };
50
+ type Email = string & { readonly __brand: unique symbol };
51
+ ```
52
+
53
+ ### 3. Functional by Default, Object-Oriented When It Fits
54
+
55
+ ```typescript
56
+ // Prefer pure functions and composition
57
+ const pipe = <T>(...fns: Array<(arg: T) => T>) =>
58
+ (value: T): T => fns.reduce((acc, fn) => fn(acc), value);
59
+
60
+ const processUser = pipe(
61
+ validateInput,
62
+ normalizeEmail,
63
+ hashPassword,
64
+ persistToDb,
65
+ );
66
+
67
+ // Use classes for stateful services with clear lifecycle
68
+ class ConnectionPool {
69
+ readonly #connections: Map<string, Connection>;
70
+ constructor(private readonly config: PoolConfig) {
71
+ this.#connections = new Map();
72
+ }
73
+ }
74
+ ```
75
+
76
+ ### 4. Performance Is a Feature
77
+
78
+ - Profile before optimizing — measure, don't guess
79
+ - Understand V8 optimization patterns (monomorphic calls, hidden classes, inline caches)
80
+ - Know when to use `Map`/`Set` over plain objects and arrays
81
+ - Avoid unnecessary allocations in hot paths
82
+ - Use `WeakRef` and `FinalizationRegistry` when appropriate
83
+
84
+ ### 5. Error Handling Is Control Flow
85
+
86
+ ```typescript
87
+ // Use Result types, not thrown exceptions for expected failures
88
+ function parseConfig(raw: string): Result<Config> {
89
+ try {
90
+ const parsed = JSON.parse(raw);
91
+ const validated = ConfigSchema.safeParse(parsed);
92
+ if (!validated.success) {
93
+ return { ok: false, error: new ValidationError(validated.error) };
94
+ }
95
+ return { ok: true, value: validated.data };
96
+ } catch {
97
+ return { ok: false, error: new ParseError('Invalid JSON') };
98
+ }
99
+ }
100
+
101
+ // Reserve throw for programmer errors (invariant violations)
102
+ function assertNonNull<T>(value: T | null | undefined, msg: string): asserts value is T {
103
+ if (value == null) throw new Error(`Invariant: ${msg}`);
104
+ }
105
+ ```
106
+
107
+ ## Project Structure
108
+
109
+ ```
110
+ src/
111
+ ├── core/ # Pure business logic, zero dependencies
112
+ ├── adapters/ # External integrations (DB, HTTP, FS)
113
+ ├── services/ # Orchestration layer
114
+ ├── utils/ # Pure utility functions
115
+ ├── types/ # TypeScript type definitions
116
+ ├── __tests__/ # Test files (co-located or centralized)
117
+ └── index.ts # Public API surface
118
+ ```
119
+
120
+ ## Definition of Done
121
+
122
+ A JavaScript feature is complete when:
123
+ - [ ] TypeScript strict mode passes with zero errors
124
+ - [ ] All code paths have explicit types (no `any`, no implicit `any`)
125
+ - [ ] Unit tests cover logic branches and edge cases
126
+ - [ ] Integration tests verify external boundaries
127
+ - [ ] Error cases are tested, not just happy paths
128
+ - [ ] No floating promises (all async paths handled)
129
+ - [ ] No memory leaks in long-running code paths
130
+ - [ ] Bundle impact assessed (for client-side code)