@ryuenn3123/agentic-senior-core 3.0.19 → 3.0.20
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/.agent-context/prompts/bootstrap-design.md +84 -103
- package/.agent-context/prompts/init-project.md +32 -100
- package/.agent-context/prompts/refactor.md +22 -44
- package/.agent-context/prompts/review-code.md +28 -52
- package/.agent-context/review-checklists/architecture-review.md +31 -62
- package/.agent-context/review-checklists/pr-checklist.md +74 -108
- package/.agent-context/rules/api-docs.md +18 -206
- package/.agent-context/rules/architecture.md +40 -207
- package/.agent-context/rules/database-design.md +10 -199
- package/.agent-context/rules/docker-runtime.md +5 -5
- package/.agent-context/rules/efficiency-vs-hype.md +11 -149
- package/.agent-context/rules/error-handling.md +9 -231
- package/.agent-context/rules/event-driven.md +17 -221
- package/.agent-context/rules/frontend-architecture.md +66 -119
- package/.agent-context/rules/git-workflow.md +1 -1
- package/.agent-context/rules/microservices.md +28 -161
- package/.agent-context/rules/naming-conv.md +8 -138
- package/.agent-context/rules/performance.md +9 -175
- package/.agent-context/rules/realtime.md +11 -44
- package/.agent-context/rules/security.md +11 -295
- package/.agent-context/rules/testing.md +9 -174
- package/.agent-context/state/benchmark-analysis.json +3 -3
- package/.agent-context/state/memory-continuity-benchmark.json +1 -1
- package/.agent-context/state/onboarding-report.json +71 -11
- package/.agents/workflows/init-project.md +7 -24
- package/.agents/workflows/refactor.md +7 -24
- package/.agents/workflows/review-code.md +7 -24
- package/.cursorrules +22 -21
- package/.gemini/instructions.md +2 -2
- package/.github/copilot-instructions.md +2 -2
- package/.instructions.md +112 -213
- package/.windsurfrules +22 -21
- package/AGENTS.md +4 -4
- package/CONTRIBUTING.md +13 -22
- package/README.md +6 -20
- package/lib/cli/commands/init.mjs +102 -148
- package/lib/cli/commands/launch.mjs +3 -3
- package/lib/cli/commands/optimize.mjs +14 -4
- package/lib/cli/commands/upgrade.mjs +25 -23
- package/lib/cli/compiler.mjs +96 -62
- package/lib/cli/constants.mjs +28 -136
- package/lib/cli/detector/design-evidence.mjs +189 -6
- package/lib/cli/detector.mjs +6 -7
- package/lib/cli/init-detection-flow.mjs +10 -93
- package/lib/cli/init-selection.mjs +2 -68
- package/lib/cli/project-scaffolder/constants.mjs +1 -1
- package/lib/cli/project-scaffolder/design-contract.mjs +162 -108
- package/lib/cli/project-scaffolder/discovery.mjs +36 -82
- package/lib/cli/project-scaffolder/prompt-builders.mjs +41 -55
- package/lib/cli/project-scaffolder/storage.mjs +0 -2
- package/lib/cli/token-optimization.mjs +1 -1
- package/lib/cli/utils.mjs +75 -9
- package/package.json +2 -2
- package/scripts/detection-benchmark.mjs +4 -15
- package/scripts/documentation-boundary-audit.mjs +9 -9
- package/scripts/explain-on-demand-audit.mjs +11 -11
- package/scripts/forbidden-content-check.mjs +9 -9
- package/scripts/frontend-usability-audit.mjs +45 -35
- package/scripts/llm-judge.mjs +1 -1
- package/scripts/mcp-server/constants.mjs +2 -2
- package/scripts/mcp-server/tool-registry.mjs +1 -1
- package/scripts/release-gate/audit-checks.mjs +4 -4
- package/scripts/release-gate/static-checks.mjs +5 -5
- package/scripts/release-gate.mjs +1 -1
- package/scripts/rules-guardian-audit.mjs +14 -13
- package/scripts/single-source-lazy-loading-audit.mjs +3 -3
- package/scripts/sync-thin-adapters.mjs +5 -5
- package/scripts/ui-design-judge/design-execution-summary.mjs +27 -1
- package/scripts/ui-design-judge/prompting.mjs +4 -4
- package/scripts/ui-design-judge/reporting.mjs +2 -1
- package/scripts/ui-design-judge/rubric-calibration.mjs +8 -5
- package/scripts/ui-design-judge/rubric-goldset.json +2 -2
- package/scripts/ui-design-judge.mjs +70 -6
- package/scripts/validate/config.mjs +138 -48
- package/scripts/validate/coverage-checks.mjs +32 -7
- package/scripts/validate.mjs +8 -4
- package/lib/cli/architect.mjs +0 -431
|
@@ -1,178 +1,12 @@
|
|
|
1
|
-
# Performance
|
|
1
|
+
# Performance Boundary
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> But ignoring obvious performance traps is just incompetence.
|
|
3
|
+
Do not over-optimize by habit. Do reject obvious scale and runtime failures.
|
|
5
4
|
|
|
6
|
-
|
|
5
|
+
Hard rejections:
|
|
6
|
+
- repeated network, database, filesystem, or model calls inside loops without batching, limits, or caching rationale
|
|
7
|
+
- unbounded reads, renders, exports, or searches when the data can grow
|
|
8
|
+
- shipping large client/runtime payloads without a reason, split point, or loading strategy
|
|
9
|
+
- synchronous blocking work in request, UI, worker, or async paths where it can stall the product
|
|
10
|
+
- caches without invalidation, expiry, ownership, and staleness trade-offs
|
|
7
11
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
## Context-Triggered Strict Audit Mode
|
|
11
|
-
|
|
12
|
-
Strict performance audits must activate automatically for:
|
|
13
|
-
- review requests
|
|
14
|
-
- PR-intent workflows (pull request preparation and merge readiness)
|
|
15
|
-
- major feature completion
|
|
16
|
-
|
|
17
|
-
Small edits stay in lightweight mode by default to avoid unnecessary heavy checks.
|
|
18
|
-
Users can always force strict performance mode manually.
|
|
19
|
-
|
|
20
|
-
BUT — there are patterns so obviously bad that they don't need benchmarks to reject.
|
|
21
|
-
Those are listed below as **Death Penalties**.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Death Penalties (Always Reject)
|
|
26
|
-
|
|
27
|
-
### 1. N+1 Queries
|
|
28
|
-
```
|
|
29
|
-
❌ INSTANT REJECTION:
|
|
30
|
-
const users = await db.query('SELECT * FROM users');
|
|
31
|
-
for (const user of users) {
|
|
32
|
-
user.orders = await db.query('SELECT * FROM orders WHERE user_id = ?', [user.id]);
|
|
33
|
-
// This runs 1 + N queries. For 1000 users = 1001 database round trips.
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
✅ REQUIRED:
|
|
37
|
-
const users = await db.query('SELECT * FROM users');
|
|
38
|
-
const userIds = users.map(u => u.id);
|
|
39
|
-
const orders = await db.query('SELECT * FROM orders WHERE user_id = ANY($1)', [userIds]);
|
|
40
|
-
// 2 queries total, regardless of user count
|
|
41
|
-
// Or use ORM eager loading / DataLoader pattern
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
**Rule:** If you see a query inside a loop, it is almost certainly an N+1 bug. Fix it with JOINs, batch queries, or DataLoader.
|
|
45
|
-
|
|
46
|
-
### 2. Unbounded Queries
|
|
47
|
-
```
|
|
48
|
-
❌ INSTANT REJECTION:
|
|
49
|
-
const allUsers = await db.query('SELECT * FROM users');
|
|
50
|
-
// In production, "users" table has 2 million rows. Enjoy your OOM.
|
|
51
|
-
|
|
52
|
-
✅ REQUIRED:
|
|
53
|
-
const users = await db.query('SELECT * FROM users LIMIT $1 OFFSET $2', [pageSize, offset]);
|
|
54
|
-
// Or use cursor-based pagination for large datasets
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
**Rule:** EVERY query that returns a list MUST have a LIMIT. APIs MUST support pagination. Default page size: 20-50.
|
|
58
|
-
|
|
59
|
-
### 3. SELECT * in Production
|
|
60
|
-
```
|
|
61
|
-
❌ BANNED:
|
|
62
|
-
SELECT * FROM users; -- Fetches 30 columns when you need 3
|
|
63
|
-
|
|
64
|
-
✅ REQUIRED:
|
|
65
|
-
SELECT id, email, display_name FROM users;
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
**Rule:** Select only the columns you need. `SELECT *` wastes bandwidth, memory, and makes schema changes dangerous.
|
|
69
|
-
|
|
70
|
-
### 4. Synchronous I/O in Async Context
|
|
71
|
-
```
|
|
72
|
-
❌ BANNED:
|
|
73
|
-
// In an async Node.js server
|
|
74
|
-
const data = fs.readFileSync('/path/to/file');
|
|
75
|
-
const result = execSync('some-command');
|
|
76
|
-
|
|
77
|
-
✅ REQUIRED:
|
|
78
|
-
const data = await fs.promises.readFile('/path/to/file');
|
|
79
|
-
const result = await exec('some-command');
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
**Rule:** In async environments (Node.js, Python asyncio), NEVER block the event loop with synchronous I/O.
|
|
83
|
-
|
|
84
|
-
---
|
|
85
|
-
|
|
86
|
-
## Optimize Only With Evidence
|
|
87
|
-
|
|
88
|
-
For everything else, follow this protocol:
|
|
89
|
-
|
|
90
|
-
### Step 1: Measure
|
|
91
|
-
```
|
|
92
|
-
// Use profiling tools, not guesses
|
|
93
|
-
console.time('operation');
|
|
94
|
-
await heavyOperation();
|
|
95
|
-
console.timeEnd('operation');
|
|
96
|
-
|
|
97
|
-
// Use proper APM: Datadog, New Relic, OpenTelemetry
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Step 2: Identify the Bottleneck
|
|
101
|
-
- Is it CPU? Memory? I/O? Network?
|
|
102
|
-
- Don't optimize CPU when the bottleneck is a slow database query
|
|
103
|
-
|
|
104
|
-
### Step 3: Optimize the Bottleneck (Not Everything Else)
|
|
105
|
-
- Fix the slowest thing first
|
|
106
|
-
- Re-measure after each change
|
|
107
|
-
- Stop when performance meets requirements
|
|
108
|
-
|
|
109
|
-
---
|
|
110
|
-
|
|
111
|
-
## Caching Rules
|
|
112
|
-
|
|
113
|
-
### When to Cache
|
|
114
|
-
- Data that is read frequently, written rarely
|
|
115
|
-
- Expensive computations that produce the same result for same inputs
|
|
116
|
-
- External API responses (respect their cache headers)
|
|
117
|
-
|
|
118
|
-
### When NOT to Cache
|
|
119
|
-
- Data that changes every request
|
|
120
|
-
- Small, fast queries (cache overhead > query time)
|
|
121
|
-
- When you can't define a clear invalidation strategy
|
|
122
|
-
|
|
123
|
-
### The Caching Devil's Triangle
|
|
124
|
-
You can have 2 of 3:
|
|
125
|
-
1. **Fresh data** (always up-to-date)
|
|
126
|
-
2. **Fast reads** (sub-millisecond)
|
|
127
|
-
3. **Simple code** (no cache layer)
|
|
128
|
-
|
|
129
|
-
Pick your 2 and document the trade-off.
|
|
130
|
-
|
|
131
|
-
### Invalidation Strategy (MANDATORY)
|
|
132
|
-
```
|
|
133
|
-
❌ BANNED:
|
|
134
|
-
cache.set('users', data); // When does this expire? Who invalidates it? Nobody knows.
|
|
135
|
-
|
|
136
|
-
✅ REQUIRED:
|
|
137
|
-
cache.set('users:active', data, { ttl: 300 }); // 5 min TTL, explicit key
|
|
138
|
-
// AND document: "Invalidated on user.created, user.deleted, user.deactivated events"
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**Rule:** NEVER add a cache without documenting the invalidation strategy. "We'll figure it out later" means "we'll have stale data in production."
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## Connection Management
|
|
146
|
-
|
|
147
|
-
1. **Use connection pools** — never open/close connections per request
|
|
148
|
-
2. **Set pool limits** — max connections based on infrastructure, not infinity
|
|
149
|
-
3. **Implement timeouts** — connection timeout, query timeout, request timeout
|
|
150
|
-
4. **Handle pool exhaustion** — fail fast with clear error, don't queue forever
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## Frontend Performance (When Applicable)
|
|
155
|
-
|
|
156
|
-
1. **Lazy load** routes and heavy components
|
|
157
|
-
2. **Debounce** search inputs and scroll handlers (300ms minimum)
|
|
158
|
-
3. **Virtualize** long lists (don't render 10,000 DOM nodes)
|
|
159
|
-
4. **Optimize images** — WebP/AVIF, responsive sizes, lazy loading
|
|
160
|
-
5. **Bundle analysis** — if your JS bundle exceeds 200KB gzipped, investigate
|
|
161
|
-
|
|
162
|
-
---
|
|
163
|
-
|
|
164
|
-
## The Performance Decision Framework
|
|
165
|
-
|
|
166
|
-
```
|
|
167
|
-
Is it a known Death Penalty pattern (N+1, unbounded, SELECT *, sync I/O)?
|
|
168
|
-
→ Yes → Fix it now, no measurement needed
|
|
169
|
-
→ No ↓
|
|
170
|
-
|
|
171
|
-
Is there a measurable performance problem?
|
|
172
|
-
→ No → Don't optimize. Ship it.
|
|
173
|
-
→ Yes ↓
|
|
174
|
-
|
|
175
|
-
Have you identified the specific bottleneck?
|
|
176
|
-
→ No → Profile first
|
|
177
|
-
→ Yes → Optimize ONLY that bottleneck, re-measure, stop when sufficient
|
|
178
|
-
```
|
|
12
|
+
When performance matters, measure the real bottleneck, change the smallest useful thing, and verify the result.
|
|
@@ -1,47 +1,14 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Realtime Boundary
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Use realtime only when the user experience needs live state, collaboration, streaming progress, notifications, or low-latency feedback. Do not add sockets by habit.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
-
|
|
8
|
-
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
-
|
|
5
|
+
Hard rules:
|
|
6
|
+
- choose the transport from product needs and current official docs: polling, server-sent events, WebSockets, WebRTC, managed realtime, or queue-backed push
|
|
7
|
+
- authenticate every connection or subscription at a trusted boundary
|
|
8
|
+
- validate every inbound message and keep message contracts typed
|
|
9
|
+
- keep business logic out of transport callbacks
|
|
10
|
+
- define reconnect, heartbeat, backpressure, rate-limit, and abuse behavior
|
|
11
|
+
- plan horizontal scaling before relying on in-memory connection state
|
|
12
|
+
- document ordering, delivery guarantees, offline behavior, and failure recovery
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
WebSockets cannot rely on traditional HTTP Authorization headers during the handshake in browser environments (as the WebSocket API does not allow setting custom headers).
|
|
15
|
-
- **Rule:** Authenticate connections explicitly.
|
|
16
|
-
- **Method A (Cookies):** If the application uses HTTPOnly cookies, authentication happens naturally during the initial HTTP upgrade request.
|
|
17
|
-
- **Method B (Tickets/Tokens):** Pass the JWT or an ephemeral ticket in the connection URL query string (`?token=xyz`) or immediately after connecting via a dedicated `auth` JSON payload.
|
|
18
|
-
- **BANNED:** Never trust a client simply because they know the WebSocket URL.
|
|
19
|
-
|
|
20
|
-
## 3. The "No Business Logic in Sockets" Rule
|
|
21
|
-
A WebSocket controller should be treated exactly like an HTTP controller.
|
|
22
|
-
- **Rule:** The WebSocket handler's **only** responsibility is parsing the incoming message, validating the payload schema, and routing it to a Service/Application layer orchestrator.
|
|
23
|
-
- **BANNED:** Directly writing to databases, executing complex business logic, or calling external APIs directly inside the WebSocket event callback.
|
|
24
|
-
|
|
25
|
-
## 4. Heartbeats & Dead Connections
|
|
26
|
-
TCP connections drop silently (e.g., when a user drives through a tunnel).
|
|
27
|
-
- **Rule:** Implement Ping/Pong heartbeats. The server MUST periodically ping the client. If the client fails to respond within the expected window (e.g., 30s), the server MUST forcefully sever the connection to free resources (`ws.terminate()`, not `ws.close()`).
|
|
28
|
-
|
|
29
|
-
## 5. Event Design & Typing
|
|
30
|
-
Treat WebSocket events like a strongly typed REST API.
|
|
31
|
-
- **Rule:** Every WebSocket message MUST have a mandatory `type` or `event` field, and a strongly typed `payload` field defined by a schema (e.g., Zod, JSON Schema).
|
|
32
|
-
- **BANNED:** Emitting arbitrary strings or untyped JSON objects like `{ user_id: 1, message: "hi" }`.
|
|
33
|
-
- **REQUIRED:**
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"event": "message.created",
|
|
37
|
-
"payload": {
|
|
38
|
-
"id": "msg_123",
|
|
39
|
-
"text": "Hello World",
|
|
40
|
-
"timestamp": "2026-03-01T12:00:00Z"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## 6. Rate Limiting & Abuse Prevention
|
|
46
|
-
WebSockets are heavily susceptible to DoS attacks because an open connection bypasses traditional WAF rate limiters.
|
|
47
|
-
- **Rule:** You MUST implement message rate limiting at the application logic layer (e.g., maximum 5 messages per second per connection/user). Violators should be instantly disconnected and IP-banned temporarily.
|
|
14
|
+
If realtime infrastructure is unresolved, the LLM must recommend the smallest current project-fit option instead of assuming WebSockets.
|
|
@@ -1,298 +1,14 @@
|
|
|
1
|
-
# Security
|
|
1
|
+
# Security Boundary
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
> You are not paranoid — you are professional.
|
|
3
|
+
Use the security model and libraries already present in the project. If security tooling is unresolved, the LLM must recommend current, maintained options from official docs and OWASP-aligned guidance before implementation.
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
-
|
|
14
|
-
- PR-intent workflows (pull request preparation and merge readiness)
|
|
15
|
-
- major feature completion
|
|
16
|
-
|
|
17
|
-
Small edits stay in lightweight mode by default to avoid unnecessary heavy checks.
|
|
18
|
-
Users can always force strict security mode manually.
|
|
19
|
-
|
|
20
|
-
System boundaries include:
|
|
21
|
-
- HTTP request bodies, query params, headers, cookies
|
|
22
|
-
- URL path parameters
|
|
23
|
-
- File uploads
|
|
24
|
-
- WebSocket messages
|
|
25
|
-
- Queue/event payloads
|
|
26
|
-
- Environment variables (at startup)
|
|
27
|
-
- Database query results (yes, even these — data could be corrupted)
|
|
28
|
-
- Third-party API responses
|
|
29
|
-
|
|
30
|
-
### Validation Protocol
|
|
31
|
-
```
|
|
32
|
-
External Input → Schema Validation (Zod/Pydantic/Bean Validation) → Typed Internal Object
|
|
33
|
-
|
|
34
|
-
NEVER:
|
|
35
|
-
External Input → Direct use in business logic
|
|
36
|
-
External Input → Direct use in database query
|
|
37
|
-
External Input → Direct interpolation into strings
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
---
|
|
41
|
-
|
|
42
|
-
## Injection Prevention
|
|
43
|
-
|
|
44
|
-
### SQL Injection — Parameterized Queries Only
|
|
45
|
-
```
|
|
46
|
-
❌ DEATH PENALTY:
|
|
47
|
-
const query = `SELECT * FROM users WHERE id = ${userId}`;
|
|
48
|
-
const query = "SELECT * FROM users WHERE name = '" + name + "'";
|
|
49
|
-
|
|
50
|
-
✅ ALWAYS:
|
|
51
|
-
const user = await db.query('SELECT * FROM users WHERE id = $1', [userId]);
|
|
52
|
-
const user = await prisma.user.findUnique({ where: { id: userId } });
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**Rule:** NEVER concatenate or interpolate user input into SQL strings. Use parameterized queries or ORMs. No exceptions. Not even "just for testing."
|
|
56
|
-
|
|
57
|
-
### Command Injection
|
|
58
|
-
```
|
|
59
|
-
❌ DEATH PENALTY:
|
|
60
|
-
exec(`convert ${filename} output.png`);
|
|
61
|
-
|
|
62
|
-
✅ ALWAYS:
|
|
63
|
-
execFile('convert', [filename, 'output.png']);
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
**Rule:** Never pass user input to shell commands via string interpolation. Use argument arrays.
|
|
67
|
-
|
|
68
|
-
### XSS Prevention
|
|
69
|
-
```
|
|
70
|
-
❌ BANNED:
|
|
71
|
-
element.innerHTML = userInput;
|
|
72
|
-
dangerouslySetInnerHTML={{ __html: userInput }};
|
|
73
|
-
|
|
74
|
-
✅ REQUIRED:
|
|
75
|
-
element.textContent = userInput;
|
|
76
|
-
// Or sanitize with DOMPurify if HTML is absolutely needed
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
**Rule:** Default to text content. Only use HTML injection with explicit sanitization AND a code comment explaining WHY.
|
|
80
|
-
|
|
81
|
-
---
|
|
82
|
-
|
|
83
|
-
## Secret Management
|
|
84
|
-
|
|
85
|
-
### Rule: ZERO Secrets in Code
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
❌ INSTANT REJECTION:
|
|
89
|
-
const API_KEY = "sk-abc123def456";
|
|
90
|
-
const DB_PASSWORD = "supersecret";
|
|
91
|
-
const JWT_SECRET = "my-jwt-secret";
|
|
92
|
-
// Even in .env.example with real values
|
|
93
|
-
|
|
94
|
-
✅ REQUIRED:
|
|
95
|
-
const API_KEY = process.env.API_KEY; // Read from environment
|
|
96
|
-
const DB_URL = process.env.DATABASE_URL; // Injected at runtime
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
### .env Files
|
|
100
|
-
- `.env` → NEVER committed (must be in `.gitignore`)
|
|
101
|
-
- `.env.example` → Committed with placeholder values ONLY (`API_KEY=your-api-key-here`)
|
|
102
|
-
- `.env.local` → NEVER committed
|
|
103
|
-
- `.env.test` → May be committed with TEST-ONLY non-secret values
|
|
104
|
-
|
|
105
|
-
### Secret Rotation
|
|
106
|
-
If a secret is accidentally committed:
|
|
107
|
-
1. Rotate the secret IMMEDIATELY (not after the PR is merged — NOW)
|
|
108
|
-
2. Remove from git history (`git filter-branch` or BFG)
|
|
109
|
-
3. Add to `.gitignore`
|
|
110
|
-
4. Document the incident
|
|
111
|
-
|
|
112
|
-
---
|
|
113
|
-
|
|
114
|
-
## Authentication & Authorization
|
|
115
|
-
|
|
116
|
-
### Authentication Rules
|
|
117
|
-
1. Never implement custom auth crypto — use established libraries (argon2, bcrypt, Passport, NextAuth)
|
|
118
|
-
2. Hash passwords with **argon2id** (OWASP primary recommendation) — bcrypt only for legacy systems
|
|
119
|
-
- Argon2id: minimum 19 MiB memory, 2 iterations, 1 parallelism
|
|
120
|
-
- bcrypt: minimum cost 12 (legacy systems only — limited to 72 bytes, no memory-hardness)
|
|
121
|
-
- NEVER: MD5, SHA1, plain SHA256, or PBKDF2 without FIPS requirement
|
|
122
|
-
3. Use constant-time comparison for tokens and hashes
|
|
123
|
-
4. Implement rate limiting on auth endpoints (max 5 attempts per minute per IP)
|
|
124
|
-
5. Session tokens must be cryptographically random (≥ 256 bits)
|
|
125
|
-
|
|
126
|
-
### Authorization Rules
|
|
127
|
-
1. **Default deny** — if no rule grants access, deny
|
|
128
|
-
2. **Server-side only** — NEVER trust client-side role checks for security
|
|
129
|
-
3. Check authorization at the service layer, not just the controller
|
|
130
|
-
4. Log all authorization failures with context (userId, resource, action)
|
|
131
|
-
|
|
132
|
-
```
|
|
133
|
-
❌ BANNED: Client-side only authorization
|
|
134
|
-
if (user.role === 'admin') { showDeleteButton(); }
|
|
135
|
-
// Attacker just changes user.role in devtools
|
|
136
|
-
|
|
137
|
-
✅ REQUIRED: Server-side enforcement
|
|
138
|
-
// Controller checks auth, service enforces business rules
|
|
139
|
-
async deleteUser(requesterId: string, targetUserId: string) {
|
|
140
|
-
const requester = await this.userRepo.findById(requesterId);
|
|
141
|
-
if (!requester || requester.role !== Role.ADMIN) {
|
|
142
|
-
throw new ForbiddenError('Insufficient permissions');
|
|
143
|
-
}
|
|
144
|
-
// ... proceed with deletion
|
|
145
|
-
}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## HTTP Security Headers
|
|
151
|
-
|
|
152
|
-
Every web application MUST include:
|
|
153
|
-
```
|
|
154
|
-
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
155
|
-
Content-Security-Policy: default-src 'self'; script-src 'self'
|
|
156
|
-
X-Content-Type-Options: nosniff
|
|
157
|
-
X-Frame-Options: DENY
|
|
158
|
-
Referrer-Policy: strict-origin-when-cross-origin
|
|
159
|
-
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### CORS
|
|
163
|
-
- NEVER use `Access-Control-Allow-Origin: *` in production
|
|
164
|
-
- Whitelist specific origins
|
|
165
|
-
- Be explicit about allowed methods and headers
|
|
166
|
-
|
|
167
|
-
---
|
|
168
|
-
|
|
169
|
-
## File Upload Security
|
|
170
|
-
|
|
171
|
-
1. Validate MIME type server-side (not just file extension)
|
|
172
|
-
2. Set maximum file size limits
|
|
173
|
-
3. Generate random filenames — never use user-provided filenames
|
|
174
|
-
4. Store uploads outside the web root
|
|
175
|
-
5. Scan for malware if accepting documents
|
|
176
|
-
|
|
177
|
-
---
|
|
178
|
-
|
|
179
|
-
## Supply Chain Security (OWASP 2025 A03)
|
|
180
|
-
|
|
181
|
-
1. **Pin all dependency versions** — use lockfiles, never `*` ranges in production
|
|
182
|
-
2. **Audit dependencies regularly** — `npm audit`, `pip audit`, `composer audit`
|
|
183
|
-
3. **Verify package integrity** — check checksums, use signed packages where available
|
|
184
|
-
4. **Minimize dependency trees** — fewer transitive dependencies = smaller attack surface
|
|
185
|
-
5. **Monitor for CVEs** — automate vulnerability scanning in CI (Dependabot, Snyk, Trivy)
|
|
186
|
-
6. **Review new dependencies** — check maintainer history, download trends, and bus factor before adding
|
|
187
|
-
|
|
188
|
-
---
|
|
189
|
-
|
|
190
|
-
## .gitignore Enforcement (Mandatory)
|
|
191
|
-
|
|
192
|
-
**If the user's INTENT is to create a new project, push to GitHub, or initialize source control, you MUST generate or verify a `.gitignore` file exists.**
|
|
193
|
-
|
|
194
|
-
### Minimum Required Entries
|
|
195
|
-
```gitignore
|
|
196
|
-
# ── Secrets & Environment ──
|
|
197
|
-
.env
|
|
198
|
-
.env.local
|
|
199
|
-
.env.*.local
|
|
200
|
-
.env.production
|
|
201
|
-
.env.staging
|
|
202
|
-
|
|
203
|
-
# ── Dependencies ──
|
|
204
|
-
node_modules/
|
|
205
|
-
vendor/
|
|
206
|
-
venv/
|
|
207
|
-
.venv/
|
|
208
|
-
__pycache__/
|
|
209
|
-
.gradle/
|
|
210
|
-
target/
|
|
211
|
-
bin/ # Go binaries
|
|
212
|
-
pkg/
|
|
213
|
-
|
|
214
|
-
# ── Build Output ──
|
|
215
|
-
dist/
|
|
216
|
-
build/
|
|
217
|
-
out/
|
|
218
|
-
*.min.js
|
|
219
|
-
*.min.css
|
|
220
|
-
.next/
|
|
221
|
-
.nuxt/
|
|
222
|
-
.output/
|
|
223
|
-
|
|
224
|
-
# ── IDE & Editor ──
|
|
225
|
-
.idea/
|
|
226
|
-
.vscode/settings.json
|
|
227
|
-
.vscode/launch.json
|
|
228
|
-
*.swp
|
|
229
|
-
*.swo
|
|
230
|
-
*~
|
|
231
|
-
|
|
232
|
-
# ── OS Artifacts ──
|
|
233
|
-
.DS_Store
|
|
234
|
-
Thumbs.db
|
|
235
|
-
Desktop.ini
|
|
236
|
-
*.lnk
|
|
237
|
-
|
|
238
|
-
# ── Logs ──
|
|
239
|
-
*.log
|
|
240
|
-
npm-debug.log*
|
|
241
|
-
yarn-debug.log*
|
|
242
|
-
pnpm-debug.log*
|
|
243
|
-
|
|
244
|
-
# ── Testing & Coverage ──
|
|
245
|
-
coverage/
|
|
246
|
-
.nyc_output/
|
|
247
|
-
*.lcov
|
|
248
|
-
|
|
249
|
-
# ── Runtime & Backup Data ──
|
|
250
|
-
*.pid
|
|
251
|
-
*.seed
|
|
252
|
-
*.pid.lock
|
|
253
|
-
.agentic-backup/
|
|
254
|
-
|
|
255
|
-
# ── Secrets & Keys ──
|
|
256
|
-
*.pem
|
|
257
|
-
*.key
|
|
258
|
-
*.p12
|
|
259
|
-
*.jks
|
|
260
|
-
*.keystore
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Rules
|
|
264
|
-
1. **NEVER commit `.env`** — only `.env.example` with placeholder values
|
|
265
|
-
2. **Check for leaks before push** — `git diff --cached --name-only | grep -E '\.(env|pem|key)$'` should return empty
|
|
266
|
-
3. **If the project has NO `.gitignore`**, create one immediately before any `git add`
|
|
267
|
-
4. **Extend per-stack** — add language-specific patterns (e.g., `__pycache__/` for Python, `target/` for Java/Rust, `.gradle/` for Kotlin)
|
|
268
|
-
5. **Reference**: See `.agent-context/rules/git-workflow.md` for the full `.gitignore Standards` section
|
|
269
|
-
|
|
270
|
-
### MUST Commit (Whitelist)
|
|
271
|
-
```
|
|
272
|
-
.env.example # Template with placeholder values ONLY
|
|
273
|
-
.editorconfig # Consistent formatting across IDEs
|
|
274
|
-
.gitignore # This file itself
|
|
275
|
-
docker-compose.yml # Dev environment definition
|
|
276
|
-
Makefile / Taskfile # Standard dev commands
|
|
277
|
-
```
|
|
278
|
-
|
|
279
|
-
---
|
|
280
|
-
|
|
281
|
-
## The Security Checklist (Quick Reference)
|
|
282
|
-
|
|
283
|
-
Before any code is "done", verify:
|
|
284
|
-
|
|
285
|
-
- [ ] All inputs validated at boundaries with schemas
|
|
286
|
-
- [ ] No string concatenation in queries/commands
|
|
287
|
-
- [ ] No secrets in source code
|
|
288
|
-
- [ ] `.gitignore` exists and covers `.env`, `node_modules/`, build output, and IDE files
|
|
289
|
-
- [ ] Authentication uses established libraries
|
|
290
|
-
- [ ] Password hashing uses argon2id (or bcrypt for legacy)
|
|
291
|
-
- [ ] Authorization enforced server-side
|
|
292
|
-
- [ ] Security headers configured
|
|
293
|
-
- [ ] CORS properly restricted
|
|
294
|
-
- [ ] Rate limiting on sensitive endpoints
|
|
295
|
-
- [ ] Error responses don't leak internal details
|
|
296
|
-
- [ ] Logging includes security events (login failures, permission denials)
|
|
297
|
-
- [ ] Dependencies audited for known vulnerabilities
|
|
5
|
+
Hard rules:
|
|
6
|
+
- validate and normalize all data crossing a trust boundary
|
|
7
|
+
- never interpolate untrusted input into queries, shell commands, file paths, templates, logs, or HTML
|
|
8
|
+
- never commit secrets, tokens, credentials, private keys, or production identifiers
|
|
9
|
+
- never invent custom crypto, session, token, or password handling when maintained standards exist
|
|
10
|
+
- enforce authorization at the server or trusted boundary, not only in UI state
|
|
11
|
+
- return safe client-facing errors and keep sensitive detail in protected logs
|
|
12
|
+
- document auth, permission, data exposure, rate-limit, and abuse assumptions before changing sensitive flows
|
|
298
13
|
|
|
14
|
+
For high-risk changes, check current framework security docs and record the relevant source or assumption in the implementation notes.
|