swe-workflow-skills 0.1.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/LICENSE +21 -0
- package/README.md +144 -0
- package/VERSION +1 -0
- package/bin/cli.mjs +44 -0
- package/catalog.json +225 -0
- package/commands/role.md +34 -0
- package/hooks/session-start.mjs +118 -0
- package/install.mjs +318 -0
- package/package.json +47 -0
- package/roles.json +194 -0
- package/scripts/resolve.mjs +296 -0
- package/skills/accessibility-design/SKILL.md +128 -0
- package/skills/accessibility-design/evals/evals.json +51 -0
- package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
- package/skills/api-design/SKILL.md +144 -0
- package/skills/api-design/evals/evals.json +48 -0
- package/skills/api-design/references/rest-conventions.md +147 -0
- package/skills/api-design/templates/api-spec.md +156 -0
- package/skills/architecture-design/SKILL.md +86 -0
- package/skills/architecture-design/evals/evals.json +44 -0
- package/skills/architecture-design/references/clean-architecture.md +147 -0
- package/skills/architecture-design/references/component-principles.md +129 -0
- package/skills/architecture-design/references/principles.md +81 -0
- package/skills/architecture-design/references/solid-principles.md +106 -0
- package/skills/architecture-design/templates/adr.md +63 -0
- package/skills/architecture-documentation/SKILL.md +126 -0
- package/skills/architecture-documentation/evals/evals.json +44 -0
- package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
- package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
- package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
- package/skills/bug-investigating/SKILL.md +133 -0
- package/skills/bug-investigating/evals/evals.json +56 -0
- package/skills/bug-investigating/references/common-bugs.md +62 -0
- package/skills/bug-investigating/references/debugging-patterns.md +94 -0
- package/skills/cicd-pipeline/SKILL.md +87 -0
- package/skills/cicd-pipeline/evals/evals.json +34 -0
- package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
- package/skills/cicd-pipeline/templates/github-actions.md +206 -0
- package/skills/code-reviewing/SKILL.md +92 -0
- package/skills/code-reviewing/evals/evals.json +62 -0
- package/skills/code-reviewing/references/error-handling.md +108 -0
- package/skills/code-reviewing/references/review-checklist.md +144 -0
- package/skills/configuration-strategy/SKILL.md +109 -0
- package/skills/configuration-strategy/evals/evals.json +41 -0
- package/skills/configuration-strategy/references/config-patterns.md +161 -0
- package/skills/containerization/SKILL.md +90 -0
- package/skills/containerization/evals/evals.json +36 -0
- package/skills/containerization/references/dockerfile-patterns.md +168 -0
- package/skills/containerization/templates/dockerfile.md +154 -0
- package/skills/data-modeling/SKILL.md +83 -0
- package/skills/data-modeling/evals/evals.json +43 -0
- package/skills/data-modeling/references/conventions.md +57 -0
- package/skills/data-modeling/templates/schema.md +120 -0
- package/skills/dependency-impact-analysis/SKILL.md +113 -0
- package/skills/dependency-impact-analysis/evals/evals.json +41 -0
- package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
- package/skills/dependency-management/SKILL.md +161 -0
- package/skills/dependency-management/evals/evals.json +48 -0
- package/skills/dependency-management/references/evaluation-checklist.md +127 -0
- package/skills/deployment-checklist/SKILL.md +132 -0
- package/skills/deployment-checklist/evals/evals.json +58 -0
- package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
- package/skills/deployment-repo/SKILL.md +190 -0
- package/skills/deployment-repo/evals/evals.json +44 -0
- package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
- package/skills/deployment-repo/references/version-compatibility.md +227 -0
- package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
- package/skills/effort-estimation/SKILL.md +95 -0
- package/skills/effort-estimation/evals/evals.json +32 -0
- package/skills/effort-estimation/references/estimation-methods.md +154 -0
- package/skills/feature-planning/SKILL.md +84 -0
- package/skills/feature-planning/evals/evals.json +44 -0
- package/skills/feature-planning/templates/plan.md +55 -0
- package/skills/feature-planning/templates/task.md +26 -0
- package/skills/frontend-architecture/SKILL.md +154 -0
- package/skills/frontend-architecture/evals/evals.json +34 -0
- package/skills/frontend-architecture/references/component-patterns.md +264 -0
- package/skills/frontend-architecture/templates/folder-structure.md +203 -0
- package/skills/git-workflow/SKILL.md +127 -0
- package/skills/git-workflow/evals/evals.json +44 -0
- package/skills/git-workflow/references/conventions.md +142 -0
- package/skills/git-workflow/templates/pull-request.md +57 -0
- package/skills/gitops-delivery/SKILL.md +319 -0
- package/skills/gitops-delivery/evals/evals.json +44 -0
- package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
- package/skills/gitops-delivery/templates/gitops-config.md +196 -0
- package/skills/incident-response/SKILL.md +130 -0
- package/skills/incident-response/evals/evals.json +55 -0
- package/skills/incident-response/references/communication-templates.md +134 -0
- package/skills/incident-response/references/severity-levels.md +77 -0
- package/skills/incident-response/templates/incident-timeline.md +57 -0
- package/skills/infrastructure-as-code/SKILL.md +86 -0
- package/skills/infrastructure-as-code/evals/evals.json +33 -0
- package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
- package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
- package/skills/metrics-and-okrs/SKILL.md +113 -0
- package/skills/metrics-and-okrs/evals/evals.json +33 -0
- package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
- package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
- package/skills/ml-experiment-tracking/SKILL.md +96 -0
- package/skills/ml-experiment-tracking/evals/evals.json +32 -0
- package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
- package/skills/ml-model-deployment/SKILL.md +106 -0
- package/skills/ml-model-deployment/evals/evals.json +34 -0
- package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
- package/skills/ml-pipeline-design/SKILL.md +162 -0
- package/skills/ml-pipeline-design/evals/evals.json +34 -0
- package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
- package/skills/observability-design/SKILL.md +162 -0
- package/skills/observability-design/evals/evals.json +52 -0
- package/skills/observability-design/references/logging-patterns.md +229 -0
- package/skills/observability-design/references/slo-framework.md +151 -0
- package/skills/observability-design/templates/slo-document.md +80 -0
- package/skills/performance-optimization/SKILL.md +83 -0
- package/skills/performance-optimization/evals/evals.json +47 -0
- package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
- package/skills/performance-optimization/references/concurrency.md +101 -0
- package/skills/prd-writing/SKILL.md +109 -0
- package/skills/prd-writing/evals/evals.json +33 -0
- package/skills/prd-writing/references/prd-examples.md +132 -0
- package/skills/prd-writing/templates/prd.md +71 -0
- package/skills/prd-writing/templates/rfc.md +79 -0
- package/skills/project-documentation/SKILL.md +104 -0
- package/skills/project-documentation/evals/evals.json +48 -0
- package/skills/project-documentation/references/contributing-guide.md +100 -0
- package/skills/project-documentation/templates/changelog.md +59 -0
- package/skills/project-documentation/templates/readme.md +121 -0
- package/skills/project-proposal/SKILL.md +90 -0
- package/skills/project-proposal/evals/evals.json +31 -0
- package/skills/project-proposal/references/proposal-examples.md +140 -0
- package/skills/project-proposal/templates/proposal.md +76 -0
- package/skills/project-review/SKILL.md +111 -0
- package/skills/project-review/evals/evals.json +42 -0
- package/skills/refactoring/SKILL.md +90 -0
- package/skills/refactoring/evals/evals.json +44 -0
- package/skills/refactoring/references/transformations.md +132 -0
- package/skills/retrospective/SKILL.md +157 -0
- package/skills/retrospective/evals/evals.json +34 -0
- package/skills/retrospective/references/facilitation-guide.md +130 -0
- package/skills/retrospective/templates/post-mortem.md +121 -0
- package/skills/rollback-strategy/SKILL.md +116 -0
- package/skills/rollback-strategy/evals/evals.json +55 -0
- package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
- package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
- package/skills/security-audit/SKILL.md +146 -0
- package/skills/security-audit/evals/evals.json +66 -0
- package/skills/security-audit/references/owasp-top-10.md +167 -0
- package/skills/security-audit/templates/security-report.md +79 -0
- package/skills/skill-router/SKILL.md +171 -0
- package/skills/skill-router/evals/evals.json +39 -0
- package/skills/strategic-review/SKILL.md +106 -0
- package/skills/strategic-review/evals/evals.json +42 -0
- package/skills/strategic-review/templates/full-review-prompt.md +84 -0
- package/skills/tdd-workflow/SKILL.md +147 -0
- package/skills/tdd-workflow/evals/evals.json +58 -0
- package/skills/tdd-workflow/references/test-quality.md +71 -0
- package/skills/technical-debt-review/SKILL.md +113 -0
- package/skills/technical-debt-review/evals/evals.json +41 -0
- package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
- package/skills/technical-debt-review/templates/debt-audit.md +85 -0
- package/skills/test-data-strategy/SKILL.md +129 -0
- package/skills/test-data-strategy/evals/evals.json +49 -0
- package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
- package/skills/test-suite-design/SKILL.md +137 -0
- package/skills/test-suite-design/evals/evals.json +69 -0
- package/skills/test-suite-design/references/test-infrastructure.md +175 -0
- package/skills/test-suite-design/references/testing-pyramid.md +140 -0
- package/skills/ui-ux-design/SKILL.md +117 -0
- package/skills/ui-ux-design/evals/evals.json +35 -0
- package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
- package/skills/ui-ux-design/templates/screen-spec.md +97 -0
- package/skills/verification-before-completion/SKILL.md +85 -0
- package/skills/verification-before-completion/evals/evals.json +53 -0
- package/skills/writing-skills/SKILL.md +87 -0
- package/skills/writing-skills/evals/evals.json +41 -0
- package/skills/writing-skills/references/pressure-testing.md +69 -0
- package/uninstall.mjs +182 -0
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Logging and Alerting Patterns
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- Structured logging design
|
|
5
|
+
- Log levels guide
|
|
6
|
+
- Correlation patterns
|
|
7
|
+
- Sensitive data handling
|
|
8
|
+
- Alerting design patterns
|
|
9
|
+
- OpenTelemetry instrumentation snippets
|
|
10
|
+
|
|
11
|
+
## Structured Logging Design
|
|
12
|
+
|
|
13
|
+
Every log entry should be a JSON object with consistent fields:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"timestamp": "2025-03-05T14:30:00.123Z",
|
|
18
|
+
"level": "error",
|
|
19
|
+
"message": "Payment processing failed",
|
|
20
|
+
"service": "payment-service",
|
|
21
|
+
"environment": "production",
|
|
22
|
+
"trace_id": "abc123def456",
|
|
23
|
+
"span_id": "789ghi",
|
|
24
|
+
"request_id": "req-001-xyz",
|
|
25
|
+
"user_id": "usr_42",
|
|
26
|
+
"error": {
|
|
27
|
+
"type": "StripeCardError",
|
|
28
|
+
"message": "Card declined",
|
|
29
|
+
"code": "card_declined"
|
|
30
|
+
},
|
|
31
|
+
"context": {
|
|
32
|
+
"order_id": "ord_123",
|
|
33
|
+
"amount_cents": 5999,
|
|
34
|
+
"currency": "USD"
|
|
35
|
+
},
|
|
36
|
+
"duration_ms": 342
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
**Required fields** (every log entry):
|
|
41
|
+
- `timestamp` — ISO 8601 UTC
|
|
42
|
+
- `level` — debug, info, warn, error, fatal
|
|
43
|
+
- `message` — human-readable summary
|
|
44
|
+
- `service` — originating service name
|
|
45
|
+
|
|
46
|
+
**Recommended fields** (when available):
|
|
47
|
+
- `trace_id`, `span_id` — for correlation with distributed traces
|
|
48
|
+
- `request_id` — for correlating all logs within a single request
|
|
49
|
+
- `user_id` — for investigating user-reported issues
|
|
50
|
+
- `environment` — dev, staging, production
|
|
51
|
+
- `duration_ms` — for operations with measurable duration
|
|
52
|
+
|
|
53
|
+
**Contextual fields** (operation-specific):
|
|
54
|
+
- Add structured context relevant to the operation (order_id, endpoint, query)
|
|
55
|
+
- Use nested objects for complex context, not flat key collision
|
|
56
|
+
|
|
57
|
+
## Log Levels Guide
|
|
58
|
+
|
|
59
|
+
| Level | When to Use | Example | Alerting |
|
|
60
|
+
|-------|-------------|---------|----------|
|
|
61
|
+
| **fatal** | System cannot continue | Unrecoverable startup failure, data corruption detected | Page immediately |
|
|
62
|
+
| **error** | Operation failed, requires attention | Payment declined, database connection failed, unhandled exception | Alert / ticket |
|
|
63
|
+
| **warn** | Unexpected but recoverable | Retry succeeded, deprecated API called, approaching rate limit | Monitor trend |
|
|
64
|
+
| **info** | Normal operations worth noting | Request completed, user logged in, deployment started | None |
|
|
65
|
+
| **debug** | Diagnostic detail | SQL query executed, cache hit/miss, intermediate calculation | Never in prod |
|
|
66
|
+
|
|
67
|
+
**Rules:**
|
|
68
|
+
- Production should run at `info` level by default
|
|
69
|
+
- `debug` in production only temporarily, for active debugging (turn off after)
|
|
70
|
+
- Every `error` log should include enough context to investigate without reproduction
|
|
71
|
+
- Never log at `error` for expected conditions (user input validation failure = `warn`, not `error`)
|
|
72
|
+
|
|
73
|
+
## Correlation Patterns
|
|
74
|
+
|
|
75
|
+
### Request-scoped correlation
|
|
76
|
+
```javascript
|
|
77
|
+
// Middleware that creates a correlation context for every request
|
|
78
|
+
app.use((req, res, next) => {
|
|
79
|
+
const requestId = req.headers['x-request-id'] || crypto.randomUUID();
|
|
80
|
+
const traceId = req.headers['traceparent']?.split('-')[1] || requestId;
|
|
81
|
+
|
|
82
|
+
// Attach to request context
|
|
83
|
+
req.context = { requestId, traceId };
|
|
84
|
+
|
|
85
|
+
// Include in all logs for this request
|
|
86
|
+
req.log = logger.child({
|
|
87
|
+
request_id: requestId,
|
|
88
|
+
trace_id: traceId,
|
|
89
|
+
method: req.method,
|
|
90
|
+
path: req.path,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
next();
|
|
94
|
+
});
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Cross-service propagation
|
|
98
|
+
When calling another service, propagate the trace context:
|
|
99
|
+
```javascript
|
|
100
|
+
// Include trace headers when making downstream calls
|
|
101
|
+
const response = await fetch('https://payment-service/charge', {
|
|
102
|
+
headers: {
|
|
103
|
+
'traceparent': `00-${traceId}-${spanId}-01`,
|
|
104
|
+
'x-request-id': requestId,
|
|
105
|
+
},
|
|
106
|
+
body: JSON.stringify(payload),
|
|
107
|
+
});
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
This allows tracing a single user request across all services it touches.
|
|
111
|
+
|
|
112
|
+
## Sensitive Data Handling
|
|
113
|
+
|
|
114
|
+
**Never log:**
|
|
115
|
+
- Passwords, tokens, API keys, secrets
|
|
116
|
+
- Full credit card numbers (log last 4 digits only)
|
|
117
|
+
- Social Security Numbers, government IDs
|
|
118
|
+
- Personal health information
|
|
119
|
+
- Full request/response bodies containing PII
|
|
120
|
+
|
|
121
|
+
**Redaction patterns:**
|
|
122
|
+
```javascript
|
|
123
|
+
function redactSensitive(obj) {
|
|
124
|
+
const sensitiveKeys = ['password', 'token', 'secret', 'authorization', 'ssn', 'credit_card'];
|
|
125
|
+
const redacted = { ...obj };
|
|
126
|
+
for (const key of Object.keys(redacted)) {
|
|
127
|
+
if (sensitiveKeys.some(s => key.toLowerCase().includes(s))) {
|
|
128
|
+
redacted[key] = '[REDACTED]';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return redacted;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Alerting Design Patterns
|
|
136
|
+
|
|
137
|
+
### Good alert anatomy
|
|
138
|
+
```yaml
|
|
139
|
+
alert: HighErrorRate
|
|
140
|
+
expr: |
|
|
141
|
+
(sum(rate(http_requests_total{status=~"5.."}[5m]))
|
|
142
|
+
/ sum(rate(http_requests_total[5m]))) > 0.01
|
|
143
|
+
for: 5m # Must persist for 5 minutes (avoid flapping)
|
|
144
|
+
labels:
|
|
145
|
+
severity: page
|
|
146
|
+
annotations:
|
|
147
|
+
summary: "Error rate above 1% for 5 minutes"
|
|
148
|
+
description: "{{ $labels.service }} error rate is {{ $value | humanizePercentage }}"
|
|
149
|
+
runbook: "https://runbooks.internal/high-error-rate"
|
|
150
|
+
dashboard: "https://grafana.internal/d/service-overview"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Alert quality checklist
|
|
154
|
+
- [ ] **Actionable**: Someone can do something about it right now
|
|
155
|
+
- [ ] **Urgent**: It needs attention now (if not, make it a ticket, not an alert)
|
|
156
|
+
- [ ] **Contextualized**: Includes which service, what metric, and links to dashboards/runbooks
|
|
157
|
+
- [ ] **Not noisy**: Fires less than once per week on average (more frequent = tune or suppress)
|
|
158
|
+
- [ ] **Tested**: Someone has verified it fires correctly and the runbook works
|
|
159
|
+
- [ ] **Has an owner**: Someone is responsible for responding
|
|
160
|
+
|
|
161
|
+
### Reducing alert fatigue
|
|
162
|
+
- Alert on symptoms (error rate, latency) not causes (CPU, memory)
|
|
163
|
+
- Use burn rate alerting instead of raw thresholds
|
|
164
|
+
- Aggregate related alerts (one "service degraded" instead of five "endpoint X failing")
|
|
165
|
+
- Auto-resolve alerts that recover within the evaluation window
|
|
166
|
+
- Review alerts monthly: if an alert never fires, remove it; if it always fires, fix or tune it
|
|
167
|
+
|
|
168
|
+
## OpenTelemetry Instrumentation Snippets
|
|
169
|
+
|
|
170
|
+
### Node.js auto-instrumentation
|
|
171
|
+
```javascript
|
|
172
|
+
// tracing.js — import before any other module
|
|
173
|
+
const { NodeSDK } = require('@opentelemetry/sdk-node');
|
|
174
|
+
const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
|
|
175
|
+
const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-http');
|
|
176
|
+
const { getNodeAutoInstrumentations } = require('@opentelemetry/auto-instrumentations-node');
|
|
177
|
+
|
|
178
|
+
const sdk = new NodeSDK({
|
|
179
|
+
traceExporter: new OTLPTraceExporter({ url: 'http://otel-collector:4318/v1/traces' }),
|
|
180
|
+
metricExporter: new OTLPMetricExporter({ url: 'http://otel-collector:4318/v1/metrics' }),
|
|
181
|
+
instrumentations: [getNodeAutoInstrumentations()],
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
sdk.start();
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
### Python auto-instrumentation
|
|
188
|
+
```python
|
|
189
|
+
# Run with: opentelemetry-instrument python app.py
|
|
190
|
+
# Or programmatically:
|
|
191
|
+
from opentelemetry import trace, metrics
|
|
192
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
193
|
+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
|
|
194
|
+
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
|
|
195
|
+
|
|
196
|
+
provider = TracerProvider()
|
|
197
|
+
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://otel-collector:4317"))
|
|
198
|
+
provider.add_span_processor(processor)
|
|
199
|
+
trace.set_tracer_provider(provider)
|
|
200
|
+
|
|
201
|
+
# Add custom spans
|
|
202
|
+
tracer = trace.get_tracer(__name__)
|
|
203
|
+
|
|
204
|
+
with tracer.start_as_current_span("process_order", attributes={"order.id": order_id}):
|
|
205
|
+
validate_order(order)
|
|
206
|
+
with tracer.start_as_current_span("charge_payment"):
|
|
207
|
+
charge_result = process_payment(order)
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### Custom metrics
|
|
211
|
+
```python
|
|
212
|
+
from opentelemetry import metrics
|
|
213
|
+
|
|
214
|
+
meter = metrics.get_meter(__name__)
|
|
215
|
+
|
|
216
|
+
# Counter — things that only go up
|
|
217
|
+
request_counter = meter.create_counter("http.requests.total", description="Total HTTP requests")
|
|
218
|
+
request_counter.add(1, {"method": "GET", "path": "/api/users", "status": 200})
|
|
219
|
+
|
|
220
|
+
# Histogram — distributions
|
|
221
|
+
latency_histogram = meter.create_histogram("http.request.duration", unit="ms")
|
|
222
|
+
latency_histogram.record(42.5, {"method": "GET", "path": "/api/users"})
|
|
223
|
+
|
|
224
|
+
# Gauge (via observable) — point-in-time values
|
|
225
|
+
def get_queue_depth(observer):
|
|
226
|
+
observer.observe(get_current_queue_size(), {"queue": "orders"})
|
|
227
|
+
|
|
228
|
+
meter.create_observable_gauge("queue.depth", callbacks=[get_queue_depth])
|
|
229
|
+
```
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# SLO Framework Reference
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- Nines table
|
|
5
|
+
- Error budget calculations
|
|
6
|
+
- SLO examples by service type
|
|
7
|
+
- Burn rate alerting
|
|
8
|
+
- Error budget policies
|
|
9
|
+
|
|
10
|
+
## Nines Table
|
|
11
|
+
|
|
12
|
+
| Availability | Annual Downtime | Monthly Downtime | Common Name |
|
|
13
|
+
|-------------|-----------------|------------------|-------------|
|
|
14
|
+
| 99% | 3.65 days | 7.3 hours | Two nines |
|
|
15
|
+
| 99.5% | 1.83 days | 3.65 hours | |
|
|
16
|
+
| 99.9% | 8.77 hours | 43.2 minutes | Three nines |
|
|
17
|
+
| 99.95% | 4.38 hours | 21.6 minutes | Three and a half nines |
|
|
18
|
+
| 99.99% | 52.6 minutes | 4.32 minutes | Four nines |
|
|
19
|
+
| 99.999% | 5.26 minutes | 26 seconds | Five nines |
|
|
20
|
+
|
|
21
|
+
Each additional nine costs roughly 10x more to achieve. Going from 99.9% to 99.99% doesn't sound like much, but it means moving from 43 minutes of monthly downtime to 4 minutes — that requires redundancy, failover, and operational maturity most teams don't have.
|
|
22
|
+
|
|
23
|
+
## Error Budget Calculations
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
Error Budget (%) = 100% - SLO (%)
|
|
27
|
+
Error Budget (time) = Error Budget (%) × Time Window
|
|
28
|
+
|
|
29
|
+
Example:
|
|
30
|
+
SLO: 99.9% over 30 days
|
|
31
|
+
Error budget: 0.1% × 30 days = 0.001 × 43,200 minutes = 43.2 minutes
|
|
32
|
+
|
|
33
|
+
If an outage lasts 15 minutes:
|
|
34
|
+
Budget consumed: 15 / 43.2 = 34.7%
|
|
35
|
+
Budget remaining: 65.3%
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
For request-based SLOs:
|
|
39
|
+
```
|
|
40
|
+
Error Budget (requests) = Total requests × (1 - SLO)
|
|
41
|
+
|
|
42
|
+
Example:
|
|
43
|
+
SLO: 99.9% success rate
|
|
44
|
+
Monthly requests: 10,000,000
|
|
45
|
+
Error budget: 10,000,000 × 0.001 = 10,000 failed requests allowed
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## SLO Examples by Service Type
|
|
49
|
+
|
|
50
|
+
### Web API
|
|
51
|
+
```
|
|
52
|
+
SLI: Availability = Requests with status < 500 / Total requests
|
|
53
|
+
SLO: 99.9% over 30 days
|
|
54
|
+
|
|
55
|
+
SLI: Latency = Requests completing in < 300ms / Total requests
|
|
56
|
+
SLO: 99% over 30 days (at P99)
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Data Pipeline
|
|
60
|
+
```
|
|
61
|
+
SLI: Freshness = Pipeline runs completing within 2 hours of schedule / Total scheduled runs
|
|
62
|
+
SLO: 99.5% over 30 days
|
|
63
|
+
|
|
64
|
+
SLI: Quality = Records passing validation / Total records processed
|
|
65
|
+
SLO: 99.9% over 30 days
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### User-Facing Web Application
|
|
69
|
+
```
|
|
70
|
+
SLI: Availability = Successful page loads / Total page load attempts
|
|
71
|
+
SLO: 99.95% over 30 days
|
|
72
|
+
|
|
73
|
+
SLI: Latency = Page loads completing in < 2s / Total page loads
|
|
74
|
+
SLO: 95% over 30 days
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Background Job / Queue Consumer
|
|
78
|
+
```
|
|
79
|
+
SLI: Processing success = Jobs completing successfully / Total jobs started
|
|
80
|
+
SLO: 99.9% over 30 days
|
|
81
|
+
|
|
82
|
+
SLI: Processing latency = Jobs completing within SLA / Total jobs
|
|
83
|
+
SLO: 99% within 5 minutes of enqueue
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Burn Rate Alerting
|
|
87
|
+
|
|
88
|
+
Raw threshold alerts ("error rate > 1%") are noisy. Burn rate alerts ask: "At the current error rate, how fast are we consuming our error budget?"
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
Burn rate = (Current error rate / Allowed error rate)
|
|
92
|
+
|
|
93
|
+
If burn rate = 1: you'll exactly exhaust budget by end of window
|
|
94
|
+
If burn rate = 10: you'll exhaust budget in 1/10th of the window
|
|
95
|
+
If burn rate = 0.5: you're consuming half the allowed rate (healthy)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Multi-window alerting (Google SRE recommendation)
|
|
99
|
+
|
|
100
|
+
| Alert Level | Long Window | Short Window | Burn Rate | Budget Consumed |
|
|
101
|
+
|-------------|-------------|--------------|-----------|-----------------|
|
|
102
|
+
| Page (urgent) | 1 hour | 5 minutes | 14.4x | 2% in 1 hour |
|
|
103
|
+
| Page (fast) | 6 hours | 30 minutes | 6x | 5% in 6 hours |
|
|
104
|
+
| Ticket (slow) | 3 days | 6 hours | 1x | 10% in 3 days |
|
|
105
|
+
|
|
106
|
+
The short window confirms the problem is still happening (not a spike that already resolved). The long window establishes the trend.
|
|
107
|
+
|
|
108
|
+
## Error Budget Policies
|
|
109
|
+
|
|
110
|
+
Document these policies and get sign-off from engineering and product leadership:
|
|
111
|
+
|
|
112
|
+
```markdown
|
|
113
|
+
## Error Budget Policy for [Service Name]
|
|
114
|
+
|
|
115
|
+
### When budget > 50% remaining
|
|
116
|
+
- Normal development velocity
|
|
117
|
+
- Deploy at normal cadence
|
|
118
|
+
- Standard review process
|
|
119
|
+
|
|
120
|
+
### When budget 25-50% remaining
|
|
121
|
+
- Review recent incidents for patterns
|
|
122
|
+
- Prioritize reliability-related tech debt
|
|
123
|
+
- Increase test coverage for affected paths
|
|
124
|
+
|
|
125
|
+
### When budget 10-25% remaining
|
|
126
|
+
- Reduce deployment frequency
|
|
127
|
+
- Require additional review for risky changes
|
|
128
|
+
- Begin reliability sprint planning
|
|
129
|
+
|
|
130
|
+
### When budget < 10% remaining
|
|
131
|
+
- Freeze all non-critical feature deployments
|
|
132
|
+
- Dedicate engineering capacity to reliability
|
|
133
|
+
- Conduct architecture review for systemic issues
|
|
134
|
+
|
|
135
|
+
### When budget is exhausted
|
|
136
|
+
- Full feature freeze until budget recovers
|
|
137
|
+
- Post-incident review required for every incident
|
|
138
|
+
- Escalate to leadership for resource allocation
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Common Mistakes in SLO Design
|
|
142
|
+
|
|
143
|
+
**Setting SLOs too high**: 99.99% sounds great but allows only 4 minutes of downtime per month. If your team can't respond to an incident in 4 minutes, this SLO is aspirational, not achievable.
|
|
144
|
+
|
|
145
|
+
**Using internal metrics as SLIs**: CPU utilization, memory usage, and queue depth are operational signals, not user experience signals. Users don't care about your CPU — they care about latency and errors.
|
|
146
|
+
|
|
147
|
+
**No error budget policy**: SLOs without consequences are decorative. Define what happens when the budget runs low.
|
|
148
|
+
|
|
149
|
+
**Too many SLOs**: 3-5 SLOs per service is sufficient. More than that dilutes focus and creates contradictory pressures.
|
|
150
|
+
|
|
151
|
+
**SLO = SLA**: Your SLO should be tighter than your SLA. The SLO is your internal early warning. If you only react at SLA boundaries, you're already failing customers.
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# SLO Document Template
|
|
2
|
+
|
|
3
|
+
```markdown
|
|
4
|
+
# SLO: [Service Name]
|
|
5
|
+
|
|
6
|
+
**Owner**: [Team / individual]
|
|
7
|
+
**Last reviewed**: [YYYY-MM-DD]
|
|
8
|
+
**Review cadence**: Quarterly
|
|
9
|
+
|
|
10
|
+
## Service Description
|
|
11
|
+
|
|
12
|
+
[1-2 sentences: what this service does and who its users are.]
|
|
13
|
+
|
|
14
|
+
## Critical User Journeys
|
|
15
|
+
|
|
16
|
+
1. [Journey 1: e.g., "User loads the product catalog"]
|
|
17
|
+
2. [Journey 2: e.g., "User completes checkout"]
|
|
18
|
+
3. [Journey 3: e.g., "User searches for products"]
|
|
19
|
+
|
|
20
|
+
## SLIs and SLOs
|
|
21
|
+
|
|
22
|
+
### SLO 1: Availability
|
|
23
|
+
|
|
24
|
+
**SLI**: Proportion of HTTP requests that return a non-5xx status code
|
|
25
|
+
**Measurement**: Load balancer access logs
|
|
26
|
+
**Window**: 30-day rolling
|
|
27
|
+
**Target**: 99.9%
|
|
28
|
+
|
|
29
|
+
**Error Budget**: 0.1% = 43.2 minutes of downtime per month
|
|
30
|
+
|
|
31
|
+
### SLO 2: Latency
|
|
32
|
+
|
|
33
|
+
**SLI**: Proportion of HTTP requests completing within 300ms
|
|
34
|
+
**Measurement**: Application-side histogram (P99)
|
|
35
|
+
**Window**: 30-day rolling
|
|
36
|
+
**Target**: 99% of requests under 300ms
|
|
37
|
+
|
|
38
|
+
### SLO 3: [Additional SLO if needed]
|
|
39
|
+
|
|
40
|
+
**SLI**: [measurement]
|
|
41
|
+
**Measurement**: [data source]
|
|
42
|
+
**Window**: [time window]
|
|
43
|
+
**Target**: [target value]
|
|
44
|
+
|
|
45
|
+
## Error Budget Policy
|
|
46
|
+
|
|
47
|
+
| Budget Remaining | Action |
|
|
48
|
+
|-----------------|--------|
|
|
49
|
+
| > 50% | Normal development velocity |
|
|
50
|
+
| 25-50% | Prioritize reliability tech debt |
|
|
51
|
+
| 10-25% | Reduce deployment frequency |
|
|
52
|
+
| < 10% | Freeze non-critical features |
|
|
53
|
+
| Exhausted | Full reliability focus |
|
|
54
|
+
|
|
55
|
+
## Alerting
|
|
56
|
+
|
|
57
|
+
| Alert | Condition | Severity | Runbook |
|
|
58
|
+
|-------|-----------|----------|---------|
|
|
59
|
+
| Fast burn | 2% budget consumed in 1 hour | Page | [link] |
|
|
60
|
+
| Slow burn | 5% budget consumed in 6 hours | Page | [link] |
|
|
61
|
+
| Trend | 10% budget consumed in 3 days | Ticket | [link] |
|
|
62
|
+
|
|
63
|
+
## Dashboard
|
|
64
|
+
|
|
65
|
+
[Link to the service dashboard]
|
|
66
|
+
|
|
67
|
+
## Dependencies
|
|
68
|
+
|
|
69
|
+
| Dependency | Their SLO | Impact if degraded |
|
|
70
|
+
|------------|-----------|-------------------|
|
|
71
|
+
| [Database] | [target] | [what breaks] |
|
|
72
|
+
| [Auth service] | [target] | [what breaks] |
|
|
73
|
+
| [External API] | [target] | [what breaks] |
|
|
74
|
+
|
|
75
|
+
## Review History
|
|
76
|
+
|
|
77
|
+
| Date | Change | Rationale |
|
|
78
|
+
|------|--------|-----------|
|
|
79
|
+
| [YYYY-MM-DD] | Initial SLO | Based on historical performance |
|
|
80
|
+
```
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance-optimization
|
|
3
|
+
description: "Identify and resolve performance bottlenecks via static analysis — N+1 queries, algorithmic complexity, query optimization, caching, memory leaks, bundle size, connection management. Triggers: this is slow, optimize, performance, N+1, query optimization, caching, bundle size, memory leak, latency, response time, scale, bottleneck."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Performance Optimization
|
|
9
|
+
|
|
10
|
+
Identify and resolve performance bottlenecks through static analysis and design review. Good performance optimization is measurement-driven — identify the bottleneck first, optimize second.
|
|
11
|
+
|
|
12
|
+
## Core Rule
|
|
13
|
+
|
|
14
|
+
**Never optimize without understanding the bottleneck.** Random optimization wastes time and often makes things worse. The workflow is always: measure → identify → optimize → verify.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
### Step 1: Understand the Problem
|
|
19
|
+
|
|
20
|
+
Before touching code, establish baselines:
|
|
21
|
+
|
|
22
|
+
- **What is slow?** Specific endpoint, page load, batch job, query?
|
|
23
|
+
- **How slow?** Current latency/throughput numbers (or perceived slowness)
|
|
24
|
+
- **What's acceptable?** Target latency, throughput, or response time
|
|
25
|
+
- **When did it start?** Was it always slow, or is this a regression?
|
|
26
|
+
- **Under what conditions?** Load-dependent, data-size-dependent, time-dependent?
|
|
27
|
+
|
|
28
|
+
If the user doesn't have measurements, help them instrument first (see Step 2). Optimization without measurement is guessing.
|
|
29
|
+
|
|
30
|
+
### Step 2: Identify the Bottleneck
|
|
31
|
+
|
|
32
|
+
The bottleneck is almost always in one of these areas. Check in this order (most common first):
|
|
33
|
+
|
|
34
|
+
1. **Database queries** — N+1 problems, missing indexes, full table scans, unoptimized joins
|
|
35
|
+
2. **External API calls** — Sequential calls that could be parallel, no caching of responses
|
|
36
|
+
3. **Algorithmic complexity** — O(n²) or worse hiding in loops, nested iterations over large datasets
|
|
37
|
+
4. **Memory usage** — Leaks, loading entire datasets into memory, unbounded caches
|
|
38
|
+
5. **Network/I/O** — Large payloads, no compression, chatty protocols, missing CDN
|
|
39
|
+
6. **Serialization** — Expensive JSON parsing/generation, unnecessary data transformation
|
|
40
|
+
7. **Concurrency issues** — Race conditions, lock contention, thread pool exhaustion, async bottlenecks. See [references/concurrency.md](references/concurrency.md) for patterns and common bugs.
|
|
41
|
+
|
|
42
|
+
See [references/bottleneck-patterns.md](references/bottleneck-patterns.md) for the detailed detection guide.
|
|
43
|
+
|
|
44
|
+
### Step 3: Analyze and Recommend
|
|
45
|
+
|
|
46
|
+
For each identified bottleneck:
|
|
47
|
+
|
|
48
|
+
1. **Explain** what the problem is and why it causes slowness
|
|
49
|
+
2. **Quantify** the impact (e.g., "This makes 50 DB queries per page load instead of 2")
|
|
50
|
+
3. **Propose** a specific fix with expected improvement
|
|
51
|
+
4. **Assess** the complexity and risk of the fix
|
|
52
|
+
|
|
53
|
+
Order recommendations by impact-to-effort ratio. The best optimizations are high impact and low effort.
|
|
54
|
+
|
|
55
|
+
### Step 4: Implement the Fix
|
|
56
|
+
|
|
57
|
+
Apply one optimization at a time. For each:
|
|
58
|
+
|
|
59
|
+
1. Write or confirm a performance test exists (even a simple timing assertion)
|
|
60
|
+
2. Apply the change
|
|
61
|
+
3. Verify the improvement
|
|
62
|
+
4. Check for regressions (functional tests still pass, other paths not degraded)
|
|
63
|
+
|
|
64
|
+
### Step 5: Verify and Document
|
|
65
|
+
|
|
66
|
+
After optimization:
|
|
67
|
+
- Compare before/after metrics
|
|
68
|
+
- Document what was changed and why (this prevents someone from "cleaning up" the optimization later)
|
|
69
|
+
- Set up monitoring to alert if performance regresses
|
|
70
|
+
|
|
71
|
+
## Anti-patterns
|
|
72
|
+
|
|
73
|
+
- **Premature optimization**: Don't optimize code that runs once at startup or handles 10 requests/day
|
|
74
|
+
- **Micro-optimization**: Don't optimize individual array operations when the real bottleneck is a database query taking 2 seconds
|
|
75
|
+
- **Caching everything**: Caches add complexity and staleness bugs. Cache only what's measured as slow and frequently accessed
|
|
76
|
+
- **Optimizing the wrong layer**: Frontend optimization won't fix a slow API. Database optimization won't fix a slow algorithm
|
|
77
|
+
- **Sacrificing readability**: If the optimization makes the code unmaintainable, it's a bad trade unless the performance gain is critical
|
|
78
|
+
|
|
79
|
+
## Principles Applied
|
|
80
|
+
|
|
81
|
+
- **KISS**: The simplest optimization that meets the target wins. Don't build a distributed cache when a database index will do.
|
|
82
|
+
- **YAGNI**: Optimize for current scale, not hypothetical future scale. Document triggers for when to revisit.
|
|
83
|
+
- **DRY**: Centralize caching logic, query optimization, and connection management — don't optimize the same pattern in 10 places.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "performance-optimization",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Our product listing page takes 4 seconds to load. Here's the endpoint:\n\napp.get('/products', async (req, res) => {\n const products = await db.products.findMany();\n for (const product of products) {\n product.category = await db.categories.findById(product.categoryId);\n product.reviews = await db.reviews.findMany({ where: { productId: product.id } });\n product.averageRating = product.reviews.reduce((sum, r) => sum + r.rating, 0) / product.reviews.length;\n product.seller = await db.users.findById(product.sellerId);\n }\n res.json(products);\n});",
|
|
7
|
+
"expected_output": "Should identify the N+1 problem as the primary bottleneck (3 queries per product in a loop), recommend eager loading or batch queries, and note the missing pagination. Should quantify the impact.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Identifies the N+1 query problem as the primary bottleneck",
|
|
10
|
+
"Quantifies the impact (if 100 products: 1 + 100 + 100 + 100 = 301 queries)",
|
|
11
|
+
"Recommends eager loading (include/join) or batch loading (IN clause)",
|
|
12
|
+
"Identifies missing pagination (loads ALL products)",
|
|
13
|
+
"Suggests computing averageRating in the database query, not in application code",
|
|
14
|
+
"Does NOT start with micro-optimizations (variable names, array methods)",
|
|
15
|
+
"Provides concrete refactored code",
|
|
16
|
+
"Suggests adding an index on reviews.productId if not present"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 2,
|
|
21
|
+
"prompt": "Our API response times are fine for small accounts but degrade badly for enterprise customers with 50K+ records. The main offender is the search endpoint. How should I approach this?",
|
|
22
|
+
"expected_output": "Should ask for the current query and indexes, suggest EXPLAIN ANALYZE, and recommend strategies for large dataset search (proper indexing, cursor pagination, search-specific solutions like Elasticsearch for complex search).",
|
|
23
|
+
"assertions": [
|
|
24
|
+
"Asks to see the current query and database schema",
|
|
25
|
+
"Suggests running EXPLAIN ANALYZE on the slow query",
|
|
26
|
+
"Identifies that OFFSET-based pagination degrades with large datasets",
|
|
27
|
+
"Recommends cursor-based pagination",
|
|
28
|
+
"Considers whether a dedicated search index (Elasticsearch, Meilisearch) is appropriate",
|
|
29
|
+
"Does NOT immediately recommend adding Redis cache as the first solution",
|
|
30
|
+
"Applies KISS — recommends database-level fixes before adding new infrastructure"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": 3,
|
|
35
|
+
"prompt": "Make this function faster:\n\nfunction findDuplicateEmails(users) {\n const duplicates = [];\n for (let i = 0; i < users.length; i++) {\n for (let j = i + 1; j < users.length; j++) {\n if (users[i].email.toLowerCase() === users[j].email.toLowerCase()) {\n if (!duplicates.includes(users[i].email.toLowerCase())) {\n duplicates.push(users[i].email.toLowerCase());\n }\n }\n }\n }\n return duplicates;\n}",
|
|
36
|
+
"expected_output": "Should identify the O(n²) nested loop plus O(n) includes() check (effectively O(n³) worst case), and refactor to O(n) using a Map/Set.",
|
|
37
|
+
"assertions": [
|
|
38
|
+
"Identifies the algorithmic complexity (O(n²) from nested loops, O(n) from includes)",
|
|
39
|
+
"Explains WHY this is slow for large arrays",
|
|
40
|
+
"Refactors to O(n) using a Map or object for counting",
|
|
41
|
+
"Uses a Set for the duplicates result (not includes() on an array)",
|
|
42
|
+
"Notes the repeated toLowerCase() calls as a secondary optimization",
|
|
43
|
+
"Provides working refactored code"
|
|
44
|
+
]
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|