@ryuenn3123/agentic-senior-core 2.0.5 → 2.0.8
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/blueprints/mobile-app.md +91 -21
- package/.agent-context/profiles/platform.md +13 -13
- package/.agent-context/profiles/regulated.md +13 -13
- package/.agent-context/profiles/startup.md +13 -13
- package/.agent-context/prompts/review-code.md +3 -3
- package/.agent-context/review-checklists/frontend-skill-parity.md +28 -28
- package/.agent-context/review-checklists/frontend-usability.md +33 -33
- package/.agent-context/review-checklists/pr-checklist.md +11 -6
- package/.agent-context/review-checklists/release-operations.md +29 -29
- package/.agent-context/rules/api-docs.md +34 -0
- package/.agent-context/skills/README.md +62 -62
- package/.agent-context/skills/backend/README.md +67 -67
- package/.agent-context/skills/backend/architecture.md +360 -360
- package/.agent-context/skills/backend/compatibility-manifest.json +8 -8
- package/.agent-context/skills/backend/data-access.md +230 -230
- package/.agent-context/skills/backend/errors.md +137 -137
- package/.agent-context/skills/backend/validation.md +116 -116
- package/.agent-context/skills/backend.md +28 -28
- package/.agent-context/skills/cli/README.md +55 -49
- package/.agent-context/skills/cli/compatibility-manifest.json +8 -8
- package/.agent-context/skills/cli/init.md +37 -37
- package/.agent-context/skills/cli/output.md +35 -35
- package/.agent-context/skills/cli/safety-telemetry.md +39 -0
- package/.agent-context/skills/cli/upgrade.md +37 -37
- package/.agent-context/skills/cli.md +31 -28
- package/.agent-context/skills/distribution/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/distribution/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/distribution/.evidence/test-report.json +8 -0
- package/.agent-context/skills/distribution/CHANGELOG.md +7 -0
- package/.agent-context/skills/distribution/README.md +27 -19
- package/.agent-context/skills/distribution/compatibility-manifest.json +8 -8
- package/.agent-context/skills/distribution/compatibility.md +31 -31
- package/.agent-context/skills/distribution/package.json +5 -0
- package/.agent-context/skills/distribution/provenance-attestation.md +47 -0
- package/.agent-context/skills/distribution/publish.md +36 -36
- package/.agent-context/skills/distribution/rollback.md +31 -31
- package/.agent-context/skills/distribution/tests/.gitkeep +1 -0
- package/.agent-context/skills/distribution.md +31 -28
- package/.agent-context/skills/frontend/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/frontend/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/frontend/.evidence/test-report.json +8 -0
- package/.agent-context/skills/frontend/CHANGELOG.md +7 -0
- package/.agent-context/skills/frontend/README.md +49 -36
- package/.agent-context/skills/frontend/accessibility.md +107 -107
- package/.agent-context/skills/frontend/compatibility-manifest.json +8 -8
- package/.agent-context/skills/frontend/conversion-clarity.md +51 -0
- package/.agent-context/skills/frontend/motion.md +66 -66
- package/.agent-context/skills/frontend/package.json +5 -0
- package/.agent-context/skills/frontend/performance.md +62 -62
- package/.agent-context/skills/frontend/responsive-delivery.md +41 -0
- package/.agent-context/skills/frontend/tests/.gitkeep +1 -0
- package/.agent-context/skills/frontend/ui-architecture.md +128 -128
- package/.agent-context/skills/frontend.md +35 -29
- package/.agent-context/skills/fullstack/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/fullstack/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/fullstack/.evidence/test-report.json +8 -0
- package/.agent-context/skills/fullstack/CHANGELOG.md +7 -0
- package/.agent-context/skills/fullstack/README.md +27 -19
- package/.agent-context/skills/fullstack/compatibility-manifest.json +8 -8
- package/.agent-context/skills/fullstack/contracts.md +52 -52
- package/.agent-context/skills/fullstack/end-to-end.md +41 -41
- package/.agent-context/skills/fullstack/feature-slicing.md +64 -64
- package/.agent-context/skills/fullstack/package.json +5 -0
- package/.agent-context/skills/fullstack/release-coordination.md +51 -0
- package/.agent-context/skills/fullstack/tests/.gitkeep +1 -0
- package/.agent-context/skills/fullstack.md +29 -26
- package/.agent-context/skills/index.json +107 -107
- package/.agent-context/skills/review-quality/.evidence/compatibility-manifest.json +9 -0
- package/.agent-context/skills/review-quality/.evidence/sbom-excerpt.json +6 -0
- package/.agent-context/skills/review-quality/.evidence/test-report.json +8 -0
- package/.agent-context/skills/review-quality/CHANGELOG.md +7 -0
- package/.agent-context/skills/review-quality/README.md +27 -19
- package/.agent-context/skills/review-quality/benchmark.md +29 -29
- package/.agent-context/skills/review-quality/compatibility-manifest.json +8 -8
- package/.agent-context/skills/review-quality/package.json +5 -0
- package/.agent-context/skills/review-quality/planning.md +37 -37
- package/.agent-context/skills/review-quality/release-decision.md +49 -0
- package/.agent-context/skills/review-quality/security.md +33 -33
- package/.agent-context/skills/review-quality/tests/.gitkeep +1 -0
- package/.agent-context/skills/review-quality.md +33 -27
- package/.agent-context/stacks/flutter.md +16 -16
- package/.agent-context/stacks/react-native.md +16 -16
- package/.agent-context/state/architecture-map.md +25 -25
- package/.agent-context/state/benchmark-analysis.json +431 -431
- package/.agent-context/state/benchmark-thresholds.json +10 -10
- package/.agent-context/state/benchmark-watchlist.json +19 -19
- package/.agent-context/state/dependency-map.md +32 -32
- package/.agent-context/state/quality-trend-report.json +16 -6
- package/.agent-context/state/skill-platform.json +38 -38
- package/.agent-context/state/weekly-governance-report.json +126 -0
- package/.agent-override.md +36 -36
- package/.cursorrules +1 -1
- package/.gemini/instructions.md +20 -20
- package/.github/ISSUE_TEMPLATE/v1.7-frontend-work-item.yml +54 -54
- package/.github/copilot-instructions.md +21 -21
- package/.github/workflows/benchmark-detection.yml +38 -38
- package/.github/workflows/benchmark-intelligence.yml +50 -50
- package/.github/workflows/frontend-usability-gate.yml +36 -36
- package/.github/workflows/governance-weekly-report.yml +43 -0
- package/.github/workflows/release-gate.yml +32 -32
- package/.github/workflows/sbom-compliance.yml +32 -32
- package/.windsurfrules +1 -1
- package/AGENTS.md +27 -27
- package/README.md +389 -368
- package/lib/cli/commands/init.mjs +13 -1
- package/lib/cli/commands/optimize.mjs +171 -171
- package/lib/cli/commands/upgrade.mjs +9 -1
- package/lib/cli/compatibility.mjs +124 -124
- package/lib/cli/constants.mjs +37 -2
- package/lib/cli/token-optimization.mjs +275 -275
- package/lib/cli/utils.mjs +24 -3
- package/mcp.json +92 -92
- package/package.json +2 -1
- package/scripts/benchmark-gate.mjs +121 -121
- package/scripts/benchmark-intelligence.mjs +140 -140
- package/scripts/detection-benchmark.mjs +138 -138
- package/scripts/frontend-usability-audit.mjs +87 -87
- package/scripts/generate-sbom.mjs +61 -61
- package/scripts/governance-weekly-report.mjs +293 -0
- package/scripts/init-project.ps1 +104 -104
- package/scripts/llm-judge.mjs +664 -664
- package/scripts/quality-trend-report.mjs +288 -288
- package/scripts/release-gate.mjs +261 -259
- package/scripts/skill-tier-policy.mjs +75 -75
- package/scripts/token-optimization-benchmark.mjs +252 -252
- package/scripts/validate.mjs +942 -865
|
@@ -1,138 +1,138 @@
|
|
|
1
|
-
# Error Handling & Recovery
|
|
2
|
-
|
|
3
|
-
**Tier:** ADVANCE | **Source:** awesome-copilot (typed errors) + antigravity (recovery patterns) + minimax (error boundary)
|
|
4
|
-
|
|
5
|
-
## Rule: Never Swallow Errors
|
|
6
|
-
|
|
7
|
-
**WRONG:**
|
|
8
|
-
```javascript
|
|
9
|
-
try {
|
|
10
|
-
const payment = await processPayment();
|
|
11
|
-
} catch (err) {
|
|
12
|
-
console.log('oops'); // <- Error lost, no recovery
|
|
13
|
-
}
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
**CORRECT:**
|
|
17
|
-
```javascript
|
|
18
|
-
try {
|
|
19
|
-
const payment = await processPayment();
|
|
20
|
-
} catch (err) {
|
|
21
|
-
if (err instanceof PaymentDeclinedError) {
|
|
22
|
-
// KNOWN: Card declined, user can try again with different card
|
|
23
|
-
throw err;
|
|
24
|
-
} else if (err instanceof NetworkTimeoutError) {
|
|
25
|
-
// MAYBE TEMPORARY: Retry with exponential backoff
|
|
26
|
-
return await retryWithBackoff(() => processPayment());
|
|
27
|
-
} else {
|
|
28
|
-
// UNKNOWN: Log + alert ops team
|
|
29
|
-
logger.error({ err, context: { customerId, amount } });
|
|
30
|
-
throw new InternalServerError('Payment processing failed');
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Typed Error Codes
|
|
38
|
-
|
|
39
|
-
Instead of generic "Error", use specific, typed errors:
|
|
40
|
-
|
|
41
|
-
### Node.js + Custom Error Classes
|
|
42
|
-
|
|
43
|
-
```javascript
|
|
44
|
-
class ApplicationError extends Error {
|
|
45
|
-
constructor(code, message, statusCode = 500, details = {}) {
|
|
46
|
-
super(message);
|
|
47
|
-
this.code = code; // Machine-readable
|
|
48
|
-
this.statusCode = statusCode; // HTTP status
|
|
49
|
-
this.details = details;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
class PaymentDeclinedError extends ApplicationError {
|
|
54
|
-
constructor(reason) {
|
|
55
|
-
super('PAYMENT_DECLINED', `Card declined: ${reason}`, 402, { reason });
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Usage in service:
|
|
60
|
-
if (customer.balance < amount) {
|
|
61
|
-
throw new PaymentDeclinedError('Insufficient funds');
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Transport layer catches and responds:
|
|
65
|
-
app.post('/payments/charge', async (req, res) => {
|
|
66
|
-
try {
|
|
67
|
-
const result = await paymentService.charge(req.body);
|
|
68
|
-
res.json(result);
|
|
69
|
-
} catch (err) {
|
|
70
|
-
if (err instanceof ApplicationError) {
|
|
71
|
-
res.status(err.statusCode).json({
|
|
72
|
-
error: err.code,
|
|
73
|
-
message: err.message,
|
|
74
|
-
details: err.details
|
|
75
|
-
});
|
|
76
|
-
} else {
|
|
77
|
-
res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
## Correlation IDs (Debug Multi-Service Requests)
|
|
86
|
-
|
|
87
|
-
When requests span multiple services, trace them with correlation IDs:
|
|
88
|
-
|
|
89
|
-
```javascript
|
|
90
|
-
// Transport layer: Generate or receive correlation ID
|
|
91
|
-
app.use((req, res, next) => {
|
|
92
|
-
req.correlationId = req.headers['x-correlation-id'] || generateUUID();
|
|
93
|
-
res.setHeader('x-correlation-id', req.correlationId);
|
|
94
|
-
next();
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
// Service layer: Attach to all logs
|
|
98
|
-
logger.info({
|
|
99
|
-
message: 'Processing payment',
|
|
100
|
-
correlationId: req.correlationId,
|
|
101
|
-
customerId,
|
|
102
|
-
amount
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
// Logs across all services will have same correlationId
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
---
|
|
109
|
-
|
|
110
|
-
## Retry Strategy
|
|
111
|
-
|
|
112
|
-
```javascript
|
|
113
|
-
async function retryWithBackoff(fn, maxAttempts = 3) {
|
|
114
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
115
|
-
try {
|
|
116
|
-
return await fn();
|
|
117
|
-
} catch (err) {
|
|
118
|
-
if (attempt === maxAttempts) throw err;
|
|
119
|
-
if (!(err instanceof NetworkTimeoutError)) throw err;
|
|
120
|
-
|
|
121
|
-
const delay = Math.pow(2, attempt - 1) * 1000; // 1s, 2s, 4s
|
|
122
|
-
await sleep(delay);
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
---
|
|
129
|
-
|
|
130
|
-
## Checklist
|
|
131
|
-
|
|
132
|
-
- [ ] All caught errors are typed (not generic `Error`)
|
|
133
|
-
- [ ] All errors have machine-readable code
|
|
134
|
-
- [ ] Production errors logged with context (correlationId, userId)
|
|
135
|
-
- [ ] Retry logic only for transient failures (timeouts, 5xx)
|
|
136
|
-
- [ ] User-level errors have helpful messages (no SQL/stack traces)
|
|
137
|
-
- [ ] Critical errors alert ops (Slack, PagerDuty)
|
|
1
|
+
# Error Handling & Recovery
|
|
2
|
+
|
|
3
|
+
**Tier:** ADVANCE | **Source:** awesome-copilot (typed errors) + antigravity (recovery patterns) + minimax (error boundary)
|
|
4
|
+
|
|
5
|
+
## Rule: Never Swallow Errors
|
|
6
|
+
|
|
7
|
+
**WRONG:**
|
|
8
|
+
```javascript
|
|
9
|
+
try {
|
|
10
|
+
const payment = await processPayment();
|
|
11
|
+
} catch (err) {
|
|
12
|
+
console.log('oops'); // <- Error lost, no recovery
|
|
13
|
+
}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**CORRECT:**
|
|
17
|
+
```javascript
|
|
18
|
+
try {
|
|
19
|
+
const payment = await processPayment();
|
|
20
|
+
} catch (err) {
|
|
21
|
+
if (err instanceof PaymentDeclinedError) {
|
|
22
|
+
// KNOWN: Card declined, user can try again with different card
|
|
23
|
+
throw err;
|
|
24
|
+
} else if (err instanceof NetworkTimeoutError) {
|
|
25
|
+
// MAYBE TEMPORARY: Retry with exponential backoff
|
|
26
|
+
return await retryWithBackoff(() => processPayment());
|
|
27
|
+
} else {
|
|
28
|
+
// UNKNOWN: Log + alert ops team
|
|
29
|
+
logger.error({ err, context: { customerId, amount } });
|
|
30
|
+
throw new InternalServerError('Payment processing failed');
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Typed Error Codes
|
|
38
|
+
|
|
39
|
+
Instead of generic "Error", use specific, typed errors:
|
|
40
|
+
|
|
41
|
+
### Node.js + Custom Error Classes
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
class ApplicationError extends Error {
|
|
45
|
+
constructor(code, message, statusCode = 500, details = {}) {
|
|
46
|
+
super(message);
|
|
47
|
+
this.code = code; // Machine-readable
|
|
48
|
+
this.statusCode = statusCode; // HTTP status
|
|
49
|
+
this.details = details;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
class PaymentDeclinedError extends ApplicationError {
|
|
54
|
+
constructor(reason) {
|
|
55
|
+
super('PAYMENT_DECLINED', `Card declined: ${reason}`, 402, { reason });
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Usage in service:
|
|
60
|
+
if (customer.balance < amount) {
|
|
61
|
+
throw new PaymentDeclinedError('Insufficient funds');
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Transport layer catches and responds:
|
|
65
|
+
app.post('/payments/charge', async (req, res) => {
|
|
66
|
+
try {
|
|
67
|
+
const result = await paymentService.charge(req.body);
|
|
68
|
+
res.json(result);
|
|
69
|
+
} catch (err) {
|
|
70
|
+
if (err instanceof ApplicationError) {
|
|
71
|
+
res.status(err.statusCode).json({
|
|
72
|
+
error: err.code,
|
|
73
|
+
message: err.message,
|
|
74
|
+
details: err.details
|
|
75
|
+
});
|
|
76
|
+
} else {
|
|
77
|
+
res.status(500).json({ error: 'INTERNAL_SERVER_ERROR' });
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Correlation IDs (Debug Multi-Service Requests)
|
|
86
|
+
|
|
87
|
+
When requests span multiple services, trace them with correlation IDs:
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
// Transport layer: Generate or receive correlation ID
|
|
91
|
+
app.use((req, res, next) => {
|
|
92
|
+
req.correlationId = req.headers['x-correlation-id'] || generateUUID();
|
|
93
|
+
res.setHeader('x-correlation-id', req.correlationId);
|
|
94
|
+
next();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
// Service layer: Attach to all logs
|
|
98
|
+
logger.info({
|
|
99
|
+
message: 'Processing payment',
|
|
100
|
+
correlationId: req.correlationId,
|
|
101
|
+
customerId,
|
|
102
|
+
amount
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
// Logs across all services will have same correlationId
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## Retry Strategy
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
async function retryWithBackoff(fn, maxAttempts = 3) {
|
|
114
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
115
|
+
try {
|
|
116
|
+
return await fn();
|
|
117
|
+
} catch (err) {
|
|
118
|
+
if (attempt === maxAttempts) throw err;
|
|
119
|
+
if (!(err instanceof NetworkTimeoutError)) throw err;
|
|
120
|
+
|
|
121
|
+
const delay = Math.pow(2, attempt - 1) * 1000; // 1s, 2s, 4s
|
|
122
|
+
await sleep(delay);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Checklist
|
|
131
|
+
|
|
132
|
+
- [ ] All caught errors are typed (not generic `Error`)
|
|
133
|
+
- [ ] All errors have machine-readable code
|
|
134
|
+
- [ ] Production errors logged with context (correlationId, userId)
|
|
135
|
+
- [ ] Retry logic only for transient failures (timeouts, 5xx)
|
|
136
|
+
- [ ] User-level errors have helpful messages (no SQL/stack traces)
|
|
137
|
+
- [ ] Critical errors alert ops (Slack, PagerDuty)
|
|
138
138
|
- Keep retry and rollback behavior explicit.
|
|
@@ -1,117 +1,117 @@
|
|
|
1
|
-
# Input Validation & Parameterized Queries
|
|
2
|
-
|
|
3
|
-
**Tier:** ADVANCE | **Source:** awesome-copilot (boundaries) + antigravity (security halt) + minimax (validation patterns)
|
|
4
|
-
|
|
5
|
-
## Why Validation at Boundaries Matters
|
|
6
|
-
|
|
7
|
-
Rule: **All external input is untrusted.** Validate at API entry point before touching business logic or database.
|
|
8
|
-
|
|
9
|
-
Common vulnerabilities when skipped:
|
|
10
|
-
- SQL injection: Unparameterized queries with user input
|
|
11
|
-
- Type confusion: String input treated as number
|
|
12
|
-
- Business logic bypass: Missing eligibility checks
|
|
13
|
-
- Data corruption: Invalid state transitions
|
|
14
|
-
|
|
15
|
-
**SECURITY HALT:** If you find unvalidated input directly in database queries, stop feature development. Fix first.
|
|
16
|
-
|
|
17
|
-
---
|
|
18
|
-
|
|
19
|
-
## Layer 1: HTTP Request Validation
|
|
20
|
-
|
|
21
|
-
Validate shape, type, required fields **before** touching service layer.
|
|
22
|
-
|
|
23
|
-
### Node.js + Zod (Type-Safe)
|
|
24
|
-
|
|
25
|
-
```javascript
|
|
26
|
-
import { z } from 'zod';
|
|
27
|
-
|
|
28
|
-
const chargeSchema = z.object({
|
|
29
|
-
amount: z.number().min(50).max(100000),
|
|
30
|
-
customerId: z.string().uuid(),
|
|
31
|
-
cardToken: z.string().min(10).max(1000),
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
app.post('/payments/charge', async (req, res) => {
|
|
35
|
-
// Validate shape + types
|
|
36
|
-
const parsed = chargeSchema.safeParse(req.body);
|
|
37
|
-
if (!parsed.success) {
|
|
38
|
-
return res.status(400).json({
|
|
39
|
-
error: 'Invalid request',
|
|
40
|
-
details: parsed.error.errors
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Now safe to pass to service
|
|
45
|
-
const result = await paymentService.charge(parsed.data);
|
|
46
|
-
res.json(result);
|
|
47
|
-
});
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### Python + Pydantic
|
|
51
|
-
|
|
52
|
-
```python
|
|
53
|
-
from pydantic import BaseModel, Field
|
|
54
|
-
|
|
55
|
-
class ChargeRequest(BaseModel):
|
|
56
|
-
amount: float = Field(..., ge=50, le=100000)
|
|
57
|
-
customer_id: str = Field(..., min_length=36, max_length=36)
|
|
58
|
-
card_token: str = Field(..., min_length=10, max_length=1000)
|
|
59
|
-
|
|
60
|
-
@app.post("/payments/charge")
|
|
61
|
-
async def charge_payment(req: ChargeRequest):
|
|
62
|
-
result = await payment_service.charge(req.dict())
|
|
63
|
-
return result
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
## Layer 2: SQL Query Parameterization
|
|
69
|
-
|
|
70
|
-
### WRONG (SQL Injection)
|
|
71
|
-
|
|
72
|
-
```javascript
|
|
73
|
-
const customerId = req.body.customerId;
|
|
74
|
-
const query = `SELECT * FROM customers WHERE id = '${customerId}'`;
|
|
75
|
-
// Input: '; DROP TABLE customers; --'
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
### CORRECT (Parameterized)
|
|
79
|
-
|
|
80
|
-
```javascript
|
|
81
|
-
await db.one(
|
|
82
|
-
'SELECT * FROM customers WHERE id = $1',
|
|
83
|
-
[customerId] // Parameterized
|
|
84
|
-
);
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## Layer 3: Business Logic Validation
|
|
90
|
-
|
|
91
|
-
```javascript
|
|
92
|
-
async charge({ amount, customerId, cardToken }) {
|
|
93
|
-
// Already validated: amount in range, customerId is UUID
|
|
94
|
-
|
|
95
|
-
// Now validate business rules
|
|
96
|
-
const customer = await customerRepo.findById(customerId);
|
|
97
|
-
if (!customer) throw new NotFoundError('Customer');
|
|
98
|
-
if (customer.status !== 'active') throw new BusinessError('Account suspended');
|
|
99
|
-
if (customer.dailyLimit && customer.dailySpent + amount > customer.dailyLimit) {
|
|
100
|
-
throw new BusinessError('Daily limit exceeded');
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Safe to proceed
|
|
104
|
-
}
|
|
105
|
-
```
|
|
106
|
-
|
|
107
|
-
---
|
|
108
|
-
|
|
109
|
-
## Checklist
|
|
110
|
-
|
|
111
|
-
- [ ] All route handlers validate request shape (Zod/Pydantic)
|
|
112
|
-
- [ ] All database queries use parameterized statements
|
|
113
|
-
- [ ] All external API responses validated before use
|
|
114
|
-
- [ ] Business rules checked in Service layer
|
|
115
|
-
- [ ] Error messages safe (no SQL leaked to client)
|
|
116
|
-
- [ ] Tests cover invalid inputs
|
|
1
|
+
# Input Validation & Parameterized Queries
|
|
2
|
+
|
|
3
|
+
**Tier:** ADVANCE | **Source:** awesome-copilot (boundaries) + antigravity (security halt) + minimax (validation patterns)
|
|
4
|
+
|
|
5
|
+
## Why Validation at Boundaries Matters
|
|
6
|
+
|
|
7
|
+
Rule: **All external input is untrusted.** Validate at API entry point before touching business logic or database.
|
|
8
|
+
|
|
9
|
+
Common vulnerabilities when skipped:
|
|
10
|
+
- SQL injection: Unparameterized queries with user input
|
|
11
|
+
- Type confusion: String input treated as number
|
|
12
|
+
- Business logic bypass: Missing eligibility checks
|
|
13
|
+
- Data corruption: Invalid state transitions
|
|
14
|
+
|
|
15
|
+
**SECURITY HALT:** If you find unvalidated input directly in database queries, stop feature development. Fix first.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Layer 1: HTTP Request Validation
|
|
20
|
+
|
|
21
|
+
Validate shape, type, required fields **before** touching service layer.
|
|
22
|
+
|
|
23
|
+
### Node.js + Zod (Type-Safe)
|
|
24
|
+
|
|
25
|
+
```javascript
|
|
26
|
+
import { z } from 'zod';
|
|
27
|
+
|
|
28
|
+
const chargeSchema = z.object({
|
|
29
|
+
amount: z.number().min(50).max(100000),
|
|
30
|
+
customerId: z.string().uuid(),
|
|
31
|
+
cardToken: z.string().min(10).max(1000),
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
app.post('/payments/charge', async (req, res) => {
|
|
35
|
+
// Validate shape + types
|
|
36
|
+
const parsed = chargeSchema.safeParse(req.body);
|
|
37
|
+
if (!parsed.success) {
|
|
38
|
+
return res.status(400).json({
|
|
39
|
+
error: 'Invalid request',
|
|
40
|
+
details: parsed.error.errors
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Now safe to pass to service
|
|
45
|
+
const result = await paymentService.charge(parsed.data);
|
|
46
|
+
res.json(result);
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Python + Pydantic
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
from pydantic import BaseModel, Field
|
|
54
|
+
|
|
55
|
+
class ChargeRequest(BaseModel):
|
|
56
|
+
amount: float = Field(..., ge=50, le=100000)
|
|
57
|
+
customer_id: str = Field(..., min_length=36, max_length=36)
|
|
58
|
+
card_token: str = Field(..., min_length=10, max_length=1000)
|
|
59
|
+
|
|
60
|
+
@app.post("/payments/charge")
|
|
61
|
+
async def charge_payment(req: ChargeRequest):
|
|
62
|
+
result = await payment_service.charge(req.dict())
|
|
63
|
+
return result
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Layer 2: SQL Query Parameterization
|
|
69
|
+
|
|
70
|
+
### WRONG (SQL Injection)
|
|
71
|
+
|
|
72
|
+
```javascript
|
|
73
|
+
const customerId = req.body.customerId;
|
|
74
|
+
const query = `SELECT * FROM customers WHERE id = '${customerId}'`;
|
|
75
|
+
// Input: '; DROP TABLE customers; --'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### CORRECT (Parameterized)
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
await db.one(
|
|
82
|
+
'SELECT * FROM customers WHERE id = $1',
|
|
83
|
+
[customerId] // Parameterized
|
|
84
|
+
);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Layer 3: Business Logic Validation
|
|
90
|
+
|
|
91
|
+
```javascript
|
|
92
|
+
async charge({ amount, customerId, cardToken }) {
|
|
93
|
+
// Already validated: amount in range, customerId is UUID
|
|
94
|
+
|
|
95
|
+
// Now validate business rules
|
|
96
|
+
const customer = await customerRepo.findById(customerId);
|
|
97
|
+
if (!customer) throw new NotFoundError('Customer');
|
|
98
|
+
if (customer.status !== 'active') throw new BusinessError('Account suspended');
|
|
99
|
+
if (customer.dailyLimit && customer.dailySpent + amount > customer.dailyLimit) {
|
|
100
|
+
throw new BusinessError('Daily limit exceeded');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Safe to proceed
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Checklist
|
|
110
|
+
|
|
111
|
+
- [ ] All route handlers validate request shape (Zod/Pydantic)
|
|
112
|
+
- [ ] All database queries use parameterized statements
|
|
113
|
+
- [ ] All external API responses validated before use
|
|
114
|
+
- [ ] Business rules checked in Service layer
|
|
115
|
+
- [ ] Error messages safe (no SQL leaked to client)
|
|
116
|
+
- [ ] Tests cover invalid inputs
|
|
117
117
|
- Keep validation deterministic and testable.
|
|
@@ -1,29 +1,29 @@
|
|
|
1
|
-
# Backend Skill Pack
|
|
2
|
-
|
|
3
|
-
Default tier: `advance`
|
|
4
|
-
|
|
5
|
-
## Purpose
|
|
6
|
-
Build backend systems with strict layer separation, typed boundaries, and operational safety.
|
|
7
|
-
|
|
8
|
-
## In Scope
|
|
9
|
-
- Transport, service, repository, and domain separation
|
|
10
|
-
- Validation at boundaries
|
|
11
|
-
- Error handling and observability
|
|
12
|
-
- Data access and transaction safety
|
|
13
|
-
- API and event contract design
|
|
14
|
-
|
|
15
|
-
## Must-Have Checks
|
|
16
|
-
- No business logic in transport layer
|
|
17
|
-
- No HTTP objects in application layer
|
|
18
|
-
- No raw SQL in controllers or services
|
|
19
|
-
- All external input validated before business logic
|
|
20
|
-
- Typed errors and explicit failure paths
|
|
21
|
-
|
|
22
|
-
## Evidence
|
|
23
|
-
- Unit and integration tests
|
|
24
|
-
- API contract docs
|
|
25
|
-
- Validation schemas
|
|
26
|
-
- Release gate output
|
|
27
|
-
|
|
28
|
-
## Fallback
|
|
1
|
+
# Backend Skill Pack
|
|
2
|
+
|
|
3
|
+
Default tier: `advance`
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
Build backend systems with strict layer separation, typed boundaries, and operational safety.
|
|
7
|
+
|
|
8
|
+
## In Scope
|
|
9
|
+
- Transport, service, repository, and domain separation
|
|
10
|
+
- Validation at boundaries
|
|
11
|
+
- Error handling and observability
|
|
12
|
+
- Data access and transaction safety
|
|
13
|
+
- API and event contract design
|
|
14
|
+
|
|
15
|
+
## Must-Have Checks
|
|
16
|
+
- No business logic in transport layer
|
|
17
|
+
- No HTTP objects in application layer
|
|
18
|
+
- No raw SQL in controllers or services
|
|
19
|
+
- All external input validated before business logic
|
|
20
|
+
- Typed errors and explicit failure paths
|
|
21
|
+
|
|
22
|
+
## Evidence
|
|
23
|
+
- Unit and integration tests
|
|
24
|
+
- API contract docs
|
|
25
|
+
- Validation schemas
|
|
26
|
+
- Release gate output
|
|
27
|
+
|
|
28
|
+
## Fallback
|
|
29
29
|
- Standard mode is allowed only for legacy compatibility and must be flagged in release evidence.
|
|
@@ -1,50 +1,56 @@
|
|
|
1
|
-
# CLI Engineering Skills
|
|
2
|
-
|
|
3
|
-
Default tier: `advance`
|
|
4
|
-
|
|
5
|
-
This domain covers command design, safe mutation workflows, and machine-readable output conventions for automation.
|
|
6
|
-
|
|
7
|
-
## Topics
|
|
8
|
-
- [Init Flow](init.md) - Deterministic project initialization with explicit write plans
|
|
9
|
-
- [Upgrade Flow](upgrade.md) - Safe upgrades with dry-run, rollback, and compatibility checks
|
|
10
|
-
- [Machine-Readable Output](output.md) - Stable JSON output and deterministic exit semantics
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
- `
|
|
28
|
-
- `npm
|
|
29
|
-
- `
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
- `
|
|
38
|
-
- `
|
|
39
|
-
- `
|
|
40
|
-
- `
|
|
41
|
-
- `mobile-
|
|
42
|
-
- `
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
1
|
+
# CLI Engineering Skills
|
|
2
|
+
|
|
3
|
+
Default tier: `advance`
|
|
4
|
+
|
|
5
|
+
This domain covers command design, safe mutation workflows, and machine-readable output conventions for automation.
|
|
6
|
+
|
|
7
|
+
## Topics
|
|
8
|
+
- [Init Flow](init.md) - Deterministic project initialization with explicit write plans
|
|
9
|
+
- [Upgrade Flow](upgrade.md) - Safe upgrades with dry-run, rollback, and compatibility checks
|
|
10
|
+
- [Machine-Readable Output](output.md) - Stable JSON output and deterministic exit semantics
|
|
11
|
+
- [Safety and Telemetry](safety-telemetry.md) - Operational signal capture and release-facing CLI governance summaries
|
|
12
|
+
|
|
13
|
+
## Operating Model
|
|
14
|
+
- Use `advance` for normal command work.
|
|
15
|
+
- Escalate to `expert` when commands mutate user state or require migration safety.
|
|
16
|
+
|
|
17
|
+
## Above-Line Additions
|
|
18
|
+
- Mandatory dry-run support for mutating commands.
|
|
19
|
+
- Structured error payloads for CI/CD and bots.
|
|
20
|
+
- Explicit rollback plans for upgrade paths.
|
|
21
|
+
- Plug-and-play init presets for common stacks and blueprints.
|
|
22
|
+
|
|
23
|
+
## Installation and Entry Paths
|
|
24
|
+
|
|
25
|
+
Choose the path that fits your workflow:
|
|
26
|
+
|
|
27
|
+
- `agentic-senior-core launch` for a numbered interactive chooser.
|
|
28
|
+
- `npm install -g @fatidaprilian/agentic-senior-core` for a global command.
|
|
29
|
+
- `npm exec --yes @fatidaprilian/agentic-senior-core init` for a one-off run.
|
|
30
|
+
- `npx @fatidaprilian/agentic-senior-core init` for a package-managed local run.
|
|
31
|
+
- GitHub template for zero-install project bootstrap.
|
|
32
|
+
|
|
33
|
+
## Preset Starts
|
|
34
|
+
|
|
35
|
+
Use presets when you want fewer choices at the start:
|
|
36
|
+
|
|
37
|
+
- `frontend-web` - TypeScript + API Next.js + balanced profile.
|
|
38
|
+
- `backend-api` - Python + FastAPI + balanced profile.
|
|
39
|
+
- `fullstack-product` - TypeScript + API Next.js + balanced profile.
|
|
40
|
+
- `platform-governance` - Go + Go service + strict profile.
|
|
41
|
+
- `mobile-react-native` - React Native + mobile app + balanced profile.
|
|
42
|
+
- `mobile-flutter` - Flutter + mobile app + balanced profile.
|
|
43
|
+
- `observability-platform` - Go + observability + strict profile.
|
|
44
|
+
- `typescript-nestjs-service` - TypeScript + NestJS module blueprint + balanced profile.
|
|
45
|
+
- `java-enterprise-api` - Java + Spring Boot API + strict profile.
|
|
46
|
+
- `dotnet-enterprise-api` - C# + ASP.NET API + strict profile.
|
|
47
|
+
- `php-laravel-api` - PHP + Laravel API + balanced profile.
|
|
48
|
+
- `kubernetes-platform` - Go + Kubernetes manifests + strict profile.
|
|
49
|
+
|
|
50
|
+
Example:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
agentic-senior-core init --preset frontend-web
|
|
54
|
+
agentic-senior-core init --preset backend-api --ci true
|
|
55
|
+
agentic-senior-core launch
|
|
50
56
|
```
|