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,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ml-pipeline-design
|
|
3
|
+
description: "Design reproducible ML training and data pipelines — ingestion, validation, feature engineering, training, evaluation, continuous training orchestration. Triggers: training pipeline, data pipeline, feature engineering, ETL for ML, continuous training, data validation, feature store, preprocessing, notebook to pipeline, orchestrate training, Airflow, Kubeflow, pipeline DAG."
|
|
4
|
+
model: opus
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# ML Pipeline Design
|
|
9
|
+
|
|
10
|
+
Design reproducible, automated ML pipelines that transform notebooks into production-grade workflows. A pipeline is the difference between "I ran this notebook and got good results" and "this system produces, validates, and deploys models automatically."
|
|
11
|
+
|
|
12
|
+
## Why Pipelines Matter
|
|
13
|
+
|
|
14
|
+
Manual ML workflows break in predictable ways:
|
|
15
|
+
- **Undocumented steps**: "You need to run cell 7 before cell 3, but skip cell 5"
|
|
16
|
+
- **Hidden state**: Notebook variables carry state between cells that isn't captured
|
|
17
|
+
- **No validation**: Bad data enters silently and produces silently bad models
|
|
18
|
+
- **No automation**: Retraining requires a human to re-run the notebook
|
|
19
|
+
- **No lineage**: "Which data produced this model?" becomes unanswerable
|
|
20
|
+
|
|
21
|
+
Pipelines solve all of these by making each step explicit, validated, and reproducible.
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
### Step 1: Map the Pipeline Stages
|
|
26
|
+
|
|
27
|
+
Every ML pipeline follows this general DAG (Directed Acyclic Graph):
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Data Ingestion → Data Validation → Feature Engineering → Data Split
|
|
31
|
+
↓
|
|
32
|
+
Model Evaluation ← Model Training ← Hyperparameter Config
|
|
33
|
+
↓
|
|
34
|
+
Model Validation → Model Registration → (Optional) Deployment
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Identify which stages the user's workflow needs. Not every project needs every stage — a simple model might skip feature stores and hyperparameter tuning.
|
|
38
|
+
|
|
39
|
+
### Step 2: Design Each Stage
|
|
40
|
+
|
|
41
|
+
**Data Ingestion:**
|
|
42
|
+
- Where does raw data come from? (Database, API, files, streaming)
|
|
43
|
+
- How is it versioned? (DVC, Delta Lake, immutable snapshots)
|
|
44
|
+
- What's the trigger? (Schedule, event, data arrival)
|
|
45
|
+
|
|
46
|
+
**Data Validation:**
|
|
47
|
+
- Schema validation: Do columns exist? Are types correct?
|
|
48
|
+
- Statistical validation: Are distributions within expected ranges?
|
|
49
|
+
- Freshness checks: Is the data recent enough?
|
|
50
|
+
- Completeness checks: Missing value rates within tolerance?
|
|
51
|
+
|
|
52
|
+
Use frameworks like Great Expectations, Pandera, or TensorFlow Data Validation. See [references/pipeline-components.md](references/pipeline-components.md).
|
|
53
|
+
|
|
54
|
+
**Feature Engineering:**
|
|
55
|
+
- Transform raw data into model-ready features
|
|
56
|
+
- Document every transformation (input → output, rationale)
|
|
57
|
+
- Ensure transformations are deterministic and reproducible
|
|
58
|
+
- Consider a feature store for features reused across models (Feast, Tecton)
|
|
59
|
+
- **Critical**: Use the same feature code for training and serving to prevent training-serving skew
|
|
60
|
+
|
|
61
|
+
**Data Split:**
|
|
62
|
+
- Train/validation/test split with consistent strategy
|
|
63
|
+
- Time-based splits for temporal data (no future leakage)
|
|
64
|
+
- Stratified splits for imbalanced classes
|
|
65
|
+
- Document the split ratios and method
|
|
66
|
+
|
|
67
|
+
**Model Training:**
|
|
68
|
+
- Parameterized: hyperparameters passed as config, not hardcoded
|
|
69
|
+
- Tracked: all runs logged to experiment tracker (use `ml-experiment-tracking` skill)
|
|
70
|
+
- Resource-aware: specify compute requirements (GPU type, memory)
|
|
71
|
+
|
|
72
|
+
**Model Evaluation:**
|
|
73
|
+
- Evaluate on held-out test set (never used during training or tuning)
|
|
74
|
+
- Compute all relevant metrics (not just accuracy)
|
|
75
|
+
- Compare against baseline model (the one currently in production)
|
|
76
|
+
- Check for fairness across segments if applicable
|
|
77
|
+
- **Gate**: Only promote models that beat the baseline by a defined threshold
|
|
78
|
+
|
|
79
|
+
**Model Validation (pre-deployment):**
|
|
80
|
+
- Inference latency meets SLA
|
|
81
|
+
- Model size fits the deployment target
|
|
82
|
+
- No prediction anomalies on a validation dataset
|
|
83
|
+
- Input/output schema matches the serving contract
|
|
84
|
+
|
|
85
|
+
### Step 3: Choose the Orchestrator
|
|
86
|
+
|
|
87
|
+
| Tool | Best For | Complexity |
|
|
88
|
+
|------|----------|------------|
|
|
89
|
+
| **Simple scripts + cron** | Single-model, small team | Low |
|
|
90
|
+
| **Airflow / Dagster** | Data engineering teams, complex DAGs | Medium |
|
|
91
|
+
| **Kubeflow Pipelines** | Kubernetes-native, large scale | High |
|
|
92
|
+
| **Vertex AI / SageMaker Pipelines** | Cloud-native, managed | Medium |
|
|
93
|
+
| **Prefect** | Python-native, modern alternative to Airflow | Medium |
|
|
94
|
+
| **GitHub Actions** | Simple CI/CD-triggered training | Low |
|
|
95
|
+
|
|
96
|
+
Start simple: scripts + cron or GitHub Actions for early-stage ML. Move to Airflow/Dagster when you have multiple pipelines and complex dependencies.
|
|
97
|
+
|
|
98
|
+
### Step 4: Implement
|
|
99
|
+
|
|
100
|
+
Write each pipeline stage as an independent, testable component:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# Each stage is a function with clear inputs and outputs
|
|
104
|
+
def ingest_data(source_config: dict) -> pd.DataFrame:
|
|
105
|
+
"""Ingest data from configured source."""
|
|
106
|
+
...
|
|
107
|
+
|
|
108
|
+
def validate_data(df: pd.DataFrame, schema: Schema) -> ValidationResult:
|
|
109
|
+
"""Validate data against expected schema and statistics."""
|
|
110
|
+
...
|
|
111
|
+
|
|
112
|
+
def engineer_features(df: pd.DataFrame, feature_config: dict) -> pd.DataFrame:
|
|
113
|
+
"""Apply feature transformations."""
|
|
114
|
+
...
|
|
115
|
+
|
|
116
|
+
def train_model(X_train, y_train, hyperparams: dict) -> Model:
|
|
117
|
+
"""Train model with given hyperparameters."""
|
|
118
|
+
...
|
|
119
|
+
|
|
120
|
+
def evaluate_model(model: Model, X_test, y_test) -> dict:
|
|
121
|
+
"""Evaluate model and return metrics dict."""
|
|
122
|
+
...
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This pattern makes each stage unit-testable, composable, and replaceable.
|
|
126
|
+
|
|
127
|
+
### Step 5: Add Data Validation Gates
|
|
128
|
+
|
|
129
|
+
Data validation is the most overlooked and most valuable pipeline component. Bad data in → bad model out, silently.
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
import pandera as pa
|
|
133
|
+
|
|
134
|
+
# Define expected schema
|
|
135
|
+
schema = pa.DataFrameSchema({
|
|
136
|
+
"user_id": pa.Column(int, nullable=False),
|
|
137
|
+
"amount": pa.Column(float, pa.Check.in_range(0, 100000)),
|
|
138
|
+
"category": pa.Column(str, pa.Check.isin(["A", "B", "C"])),
|
|
139
|
+
"timestamp": pa.Column(pd.Timestamp, nullable=False),
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
# Validate before training
|
|
143
|
+
validated_df = schema.validate(raw_df) # Raises on failure
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Step 6: Validate and Document
|
|
147
|
+
|
|
148
|
+
- [ ] Pipeline runs end-to-end from raw data to registered model
|
|
149
|
+
- [ ] Each stage can be run independently for debugging
|
|
150
|
+
- [ ] Data validation catches bad data before training
|
|
151
|
+
- [ ] Experiment tracking captures all runs
|
|
152
|
+
- [ ] Model evaluation gates prevent worse models from being promoted
|
|
153
|
+
- [ ] Pipeline configuration is version-controlled (not hardcoded)
|
|
154
|
+
- [ ] Feature transformations are shared between training and serving
|
|
155
|
+
|
|
156
|
+
## Principles Applied
|
|
157
|
+
|
|
158
|
+
- **DRY**: Share feature engineering code between training pipeline and serving. One transformation definition, used everywhere.
|
|
159
|
+
- **KISS**: Start with a linear script, refactor into a DAG when complexity demands it. Don't adopt Kubeflow for one model.
|
|
160
|
+
- **YAGNI**: Don't build a feature store for 3 features. Build it when you have 50+ features shared across multiple models.
|
|
161
|
+
- **Functional Independence**: Each pipeline stage is an independent component with defined inputs and outputs. Replace any stage without rewriting the pipeline.
|
|
162
|
+
- **Fail fast**: Validate data at ingestion, not after 2 hours of training.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "ml-pipeline-design",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I have a Jupyter notebook that trains a customer churn prediction model. It loads data from a PostgreSQL database, does feature engineering (one-hot encoding, aggregations), trains an XGBoost model, and evaluates it. I want to turn this into a proper automated pipeline that retrains weekly. We use Python and have access to AWS.",
|
|
7
|
+
"expected_output": "Should design a pipeline DAG with separate stages, add data validation, recommend an appropriate orchestrator, ensure feature engineering is shared with serving, and set up scheduling.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Breaks the notebook into discrete pipeline stages (ingest, validate, features, train, evaluate)",
|
|
10
|
+
"Adds data validation between ingestion and feature engineering",
|
|
11
|
+
"Recommends appropriate orchestrator for the team size (not Kubeflow for one model)",
|
|
12
|
+
"Ensures feature engineering code is reusable for serving",
|
|
13
|
+
"Parameterizes hyperparameters and data source config",
|
|
14
|
+
"Includes model evaluation gate (only register if better than current)",
|
|
15
|
+
"Sets up weekly scheduling",
|
|
16
|
+
"Includes experiment tracking integration"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 2,
|
|
21
|
+
"prompt": "Our training pipeline keeps producing bad models. Sometimes the accuracy drops from 92% to 60% overnight. We suspect it's a data issue but we're not sure. How do we prevent this?",
|
|
22
|
+
"expected_output": "Should diagnose as missing data validation and recommend adding validation gates at ingestion. Should design specific checks for the kinds of data issues that cause 30% accuracy drops.",
|
|
23
|
+
"assertions": [
|
|
24
|
+
"Identifies missing data validation as the root cause",
|
|
25
|
+
"Recommends schema validation (column existence, types)",
|
|
26
|
+
"Recommends statistical validation (distribution checks, null rates)",
|
|
27
|
+
"Recommends volume checks (row count within expected range)",
|
|
28
|
+
"Suggests comparing incoming data against a training baseline",
|
|
29
|
+
"Recommends the pipeline should FAIL on bad data, not train on it",
|
|
30
|
+
"Provides concrete implementation (Great Expectations or Pandera)"
|
|
31
|
+
]
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Pipeline Components
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- Data validation frameworks
|
|
5
|
+
- Feature store patterns
|
|
6
|
+
- Pipeline testing strategies
|
|
7
|
+
- Notebook-to-pipeline migration
|
|
8
|
+
|
|
9
|
+
## Data Validation Frameworks
|
|
10
|
+
|
|
11
|
+
### Great Expectations
|
|
12
|
+
```python
|
|
13
|
+
import great_expectations as gx
|
|
14
|
+
|
|
15
|
+
context = gx.get_context()
|
|
16
|
+
|
|
17
|
+
# Define expectations
|
|
18
|
+
suite = context.add_expectation_suite("training_data_suite")
|
|
19
|
+
|
|
20
|
+
# Column existence and types
|
|
21
|
+
suite.add_expectation(gx.expectations.ExpectColumnToExist(column="user_id"))
|
|
22
|
+
suite.add_expectation(gx.expectations.ExpectColumnValuesToBeBetween(
|
|
23
|
+
column="amount", min_value=0, max_value=100000
|
|
24
|
+
))
|
|
25
|
+
suite.add_expectation(gx.expectations.ExpectColumnValuesToNotBeNull(column="user_id"))
|
|
26
|
+
suite.add_expectation(gx.expectations.ExpectColumnDistinctValuesToBeInSet(
|
|
27
|
+
column="category", value_set=["A", "B", "C"]
|
|
28
|
+
))
|
|
29
|
+
|
|
30
|
+
# Statistical expectations
|
|
31
|
+
suite.add_expectation(gx.expectations.ExpectColumnMeanToBeBetween(
|
|
32
|
+
column="amount", min_value=50, max_value=500
|
|
33
|
+
))
|
|
34
|
+
|
|
35
|
+
# Run validation
|
|
36
|
+
results = context.run_checkpoint(checkpoint_name="training_data_check")
|
|
37
|
+
if not results.success:
|
|
38
|
+
raise ValueError(f"Data validation failed: {results}")
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Pandera (lightweight, Pandas-native)
|
|
42
|
+
```python
|
|
43
|
+
import pandera as pa
|
|
44
|
+
|
|
45
|
+
schema = pa.DataFrameSchema(
|
|
46
|
+
columns={
|
|
47
|
+
"user_id": pa.Column(int, nullable=False, unique=True),
|
|
48
|
+
"amount": pa.Column(float, checks=[
|
|
49
|
+
pa.Check.in_range(0, 100000),
|
|
50
|
+
pa.Check(lambda s: s.mean() > 10, error="Mean amount suspiciously low")
|
|
51
|
+
]),
|
|
52
|
+
"label": pa.Column(int, checks=pa.Check.isin([0, 1])),
|
|
53
|
+
},
|
|
54
|
+
checks=[
|
|
55
|
+
pa.Check(lambda df: len(df) > 1000, error="Dataset too small for training"),
|
|
56
|
+
]
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
validated_df = schema.validate(raw_df)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### What to Validate
|
|
63
|
+
|
|
64
|
+
| Check Type | Example | Why |
|
|
65
|
+
|-----------|---------|-----|
|
|
66
|
+
| Schema | All expected columns exist with correct types | Catches upstream schema changes |
|
|
67
|
+
| Completeness | Null rate < 5% for critical columns | Prevents silent data loss |
|
|
68
|
+
| Range | Amount between 0 and 100K | Catches data corruption or unit changes |
|
|
69
|
+
| Distribution | Mean within 2σ of historical baseline | Catches data drift before training |
|
|
70
|
+
| Freshness | Most recent record within last 24 hours | Catches stale data pipelines |
|
|
71
|
+
| Volume | Row count within expected range | Catches missing or duplicated data |
|
|
72
|
+
| Uniqueness | No duplicate IDs in primary key columns | Catches join explosions |
|
|
73
|
+
|
|
74
|
+
## Feature Store Patterns
|
|
75
|
+
|
|
76
|
+
### When to use a feature store
|
|
77
|
+
|
|
78
|
+
Use a feature store when:
|
|
79
|
+
- Multiple models share the same features
|
|
80
|
+
- Training-serving skew is a known problem
|
|
81
|
+
- Features require complex computation (aggregations over time windows)
|
|
82
|
+
- You need point-in-time correctness for training data
|
|
83
|
+
|
|
84
|
+
Don't use a feature store when:
|
|
85
|
+
- You have one model with simple features
|
|
86
|
+
- Features are raw columns with minimal transformation
|
|
87
|
+
- The overhead of running a feature store exceeds the benefit
|
|
88
|
+
|
|
89
|
+
### Feast (open-source) minimal setup
|
|
90
|
+
```python
|
|
91
|
+
# feature_store.yaml
|
|
92
|
+
project: my_ml_project
|
|
93
|
+
registry: data/registry.db
|
|
94
|
+
provider: local
|
|
95
|
+
online_store:
|
|
96
|
+
type: sqlite
|
|
97
|
+
path: data/online_store.db
|
|
98
|
+
|
|
99
|
+
# feature_definitions.py
|
|
100
|
+
from feast import Entity, FeatureView, Field, FileSource
|
|
101
|
+
from feast.types import Float32, Int64
|
|
102
|
+
|
|
103
|
+
user = Entity(name="user", join_keys=["user_id"])
|
|
104
|
+
|
|
105
|
+
user_features = FeatureView(
|
|
106
|
+
name="user_features",
|
|
107
|
+
entities=[user],
|
|
108
|
+
schema=[
|
|
109
|
+
Field(name="avg_transaction_amount_30d", dtype=Float32),
|
|
110
|
+
Field(name="transaction_count_7d", dtype=Int64),
|
|
111
|
+
Field(name="days_since_last_login", dtype=Int64),
|
|
112
|
+
],
|
|
113
|
+
source=FileSource(path="data/user_features.parquet", timestamp_field="event_timestamp"),
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Pipeline Testing Strategies
|
|
118
|
+
|
|
119
|
+
### Unit tests for pipeline components
|
|
120
|
+
```python
|
|
121
|
+
def test_feature_engineering():
|
|
122
|
+
"""Test that feature engineering produces expected output."""
|
|
123
|
+
input_df = pd.DataFrame({
|
|
124
|
+
"amount": [100, 200, 300],
|
|
125
|
+
"timestamp": pd.to_datetime(["2025-01-01", "2025-01-02", "2025-01-03"]),
|
|
126
|
+
})
|
|
127
|
+
result = engineer_features(input_df)
|
|
128
|
+
assert "amount_log" in result.columns
|
|
129
|
+
assert "day_of_week" in result.columns
|
|
130
|
+
assert result["amount_log"].iloc[0] == pytest.approx(np.log1p(100))
|
|
131
|
+
|
|
132
|
+
def test_data_validation_rejects_bad_data():
|
|
133
|
+
"""Test that validation catches corrupt data."""
|
|
134
|
+
bad_df = pd.DataFrame({"amount": [-100, None, 999999999]})
|
|
135
|
+
with pytest.raises(pa.errors.SchemaError):
|
|
136
|
+
schema.validate(bad_df)
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Integration tests for pipeline
|
|
140
|
+
```python
|
|
141
|
+
def test_pipeline_end_to_end():
|
|
142
|
+
"""Test full pipeline with small sample data."""
|
|
143
|
+
result = run_pipeline(
|
|
144
|
+
data_source="tests/fixtures/sample_data.csv",
|
|
145
|
+
config={"max_epochs": 2, "test_mode": True}
|
|
146
|
+
)
|
|
147
|
+
assert result.model is not None
|
|
148
|
+
assert result.metrics["accuracy"] > 0.5 # Sanity check, not quality check
|
|
149
|
+
assert result.artifacts_saved
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Notebook-to-Pipeline Migration
|
|
153
|
+
|
|
154
|
+
### Step-by-step process
|
|
155
|
+
|
|
156
|
+
1. **Extract functions**: Every cell block that does a distinct thing becomes a function with typed inputs and outputs.
|
|
157
|
+
|
|
158
|
+
2. **Eliminate hidden state**: If cell 7 depends on a variable defined in cell 3, make it an explicit function parameter.
|
|
159
|
+
|
|
160
|
+
3. **Add data validation**: Between ingestion and feature engineering, between feature engineering and training.
|
|
161
|
+
|
|
162
|
+
4. **Parameterize**: Hardcoded paths, hyperparameters, and thresholds become config parameters.
|
|
163
|
+
|
|
164
|
+
5. **Add logging**: Replace print statements with proper logging. Log to experiment tracker.
|
|
165
|
+
|
|
166
|
+
6. **Write tests**: Test each extracted function independently with known inputs/outputs.
|
|
167
|
+
|
|
168
|
+
7. **Orchestrate**: Chain functions in a pipeline script or DAG definition.
|
|
169
|
+
|
|
170
|
+
### What to preserve from notebooks
|
|
171
|
+
|
|
172
|
+
- **Visualizations**: Move to a separate analysis notebook or generate as pipeline artifacts
|
|
173
|
+
- **EDA code**: Keep in a separate exploration notebook, not in the pipeline
|
|
174
|
+
- **Scratch experiments**: Archive in an experiments directory, don't delete
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: observability-design
|
|
3
|
+
description: "Design production observability — SLIs, SLOs, SLAs, error budgets, OpenTelemetry traces/metrics/logs, structured logging, alerting, dashboards. Triggers: SLO, SLI, SLA, error budget, observability, monitoring, OpenTelemetry, OTel, tracing, distributed tracing, structured logging, alerting, dashboard, metrics, correlation ID, alert fatigue."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Observability Design
|
|
9
|
+
|
|
10
|
+
Design observability systems that answer "is the system healthy?" before users complain, and "why is it broken?" when they do. Good observability means you don't need to add more instrumentation to debug an issue — the signals are already there.
|
|
11
|
+
|
|
12
|
+
## The Three Pillars + Reliability Framework
|
|
13
|
+
|
|
14
|
+
Observability has three signal types (metrics, logs, traces) and one decision framework (SLIs/SLOs/error budgets). This skill covers all four.
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
SLIs/SLOs/Error Budgets → WHAT to measure and WHEN to act
|
|
18
|
+
Metrics → HOW MUCH is happening (counters, gauges, histograms)
|
|
19
|
+
Logs → WHAT happened in detail (events, errors, context)
|
|
20
|
+
Traces → WHERE time was spent across services (request flow)
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Workflow: SLI/SLO Design
|
|
24
|
+
|
|
25
|
+
### Step 1: Identify Critical User Journeys
|
|
26
|
+
|
|
27
|
+
Before defining metrics, identify the 3-5 user-facing interactions that matter most:
|
|
28
|
+
|
|
29
|
+
- What does a user do when the service is "working"? (Load a page, complete a checkout, send a message)
|
|
30
|
+
- What would a user notice if the service degraded? (Slow responses, errors, stale data)
|
|
31
|
+
|
|
32
|
+
SLIs must reflect user experience. Internal metrics (CPU usage, queue depth) are useful for debugging but should not be SLIs — users don't care about CPU.
|
|
33
|
+
|
|
34
|
+
### Step 2: Define SLIs
|
|
35
|
+
|
|
36
|
+
For each critical journey, define 1-2 SLIs. Express each SLI as a ratio:
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
SLI = (good events / total events) × 100%
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Common SLI types:
|
|
43
|
+
|
|
44
|
+
| SLI Type | Formula | Good For |
|
|
45
|
+
|----------|---------|----------|
|
|
46
|
+
| **Availability** | Successful requests / Total requests | APIs, web apps |
|
|
47
|
+
| **Latency** | Requests < threshold / Total requests | User-facing endpoints |
|
|
48
|
+
| **Quality** | Correct responses / Total responses | Data pipelines, ML serving |
|
|
49
|
+
| **Freshness** | Data updated within threshold / Total checks | Caches, dashboards, feeds |
|
|
50
|
+
|
|
51
|
+
Measure SLIs at the point closest to the user — load balancer logs or client-side metrics, not server-side process metrics.
|
|
52
|
+
|
|
53
|
+
### Step 3: Set SLO Targets
|
|
54
|
+
|
|
55
|
+
An SLO is the target value for an SLI over a rolling time window:
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
"99.9% of requests will succeed within 300ms over a 30-day rolling window"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Setting the right target:
|
|
62
|
+
|
|
63
|
+
- **Don't base SLOs on current performance** — you'll lock yourself into an unsustainable target
|
|
64
|
+
- **Start with user expectations** — what would cause a user to complain or leave?
|
|
65
|
+
- **Leave room for innovation** — 99.99% uptime allows 4.3 minutes/month of downtime. 99.9% allows 43 minutes. That difference is engineering velocity.
|
|
66
|
+
- **Set SLOs tighter than SLAs** — your SLO should trigger action before you breach your SLA
|
|
67
|
+
|
|
68
|
+
See [references/slo-framework.md](references/slo-framework.md) for the nines table, error budget calculations, and SLO examples by service type.
|
|
69
|
+
|
|
70
|
+
### Step 4: Calculate Error Budget
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Error Budget = 100% - SLO target
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
If your SLO is 99.9% availability over 30 days:
|
|
77
|
+
- Error budget = 0.1% = 43.2 minutes of downtime per month
|
|
78
|
+
- Each incident consumes a portion of this budget
|
|
79
|
+
|
|
80
|
+
Error budget policies define what happens when the budget runs low:
|
|
81
|
+
|
|
82
|
+
- **Budget > 50% remaining**: Ship features normally
|
|
83
|
+
- **Budget 25-50%**: Reduce deployment velocity, increase review rigor
|
|
84
|
+
- **Budget < 25%**: Freeze non-critical deploys, focus on reliability
|
|
85
|
+
- **Budget exhausted**: Full reliability focus until budget replenishes
|
|
86
|
+
|
|
87
|
+
### Step 5: Document and Communicate
|
|
88
|
+
|
|
89
|
+
Save the SLO document using the template at [templates/slo-document.md](templates/slo-document.md). Share with engineering, product, and on-call teams.
|
|
90
|
+
|
|
91
|
+
## Workflow: OpenTelemetry Instrumentation
|
|
92
|
+
|
|
93
|
+
### Step 1: Choose What to Instrument
|
|
94
|
+
|
|
95
|
+
Don't instrument everything — instrument what matters:
|
|
96
|
+
|
|
97
|
+
**Always instrument:**
|
|
98
|
+
- HTTP/gRPC request handling (latency, status codes, paths)
|
|
99
|
+
- Database queries (duration, query type, table)
|
|
100
|
+
- External API calls (duration, status, endpoint)
|
|
101
|
+
- Queue operations (publish, consume, processing time)
|
|
102
|
+
- Authentication events (success, failure, method)
|
|
103
|
+
|
|
104
|
+
**Instrument when needed:**
|
|
105
|
+
- Business-specific operations (checkout, search, upload)
|
|
106
|
+
- Cache operations (hit/miss ratio, latency)
|
|
107
|
+
- Background jobs (duration, success/failure)
|
|
108
|
+
|
|
109
|
+
### Step 2: Implement the Three Signals
|
|
110
|
+
|
|
111
|
+
**Metrics** (aggregated measurements over time):
|
|
112
|
+
- Use counters for events that only go up (requests, errors, bytes sent)
|
|
113
|
+
- Use histograms for distributions (latency, request size)
|
|
114
|
+
- Use gauges for point-in-time values (queue depth, active connections)
|
|
115
|
+
- Follow OpenTelemetry semantic conventions for naming
|
|
116
|
+
|
|
117
|
+
**Traces** (request flow across services):
|
|
118
|
+
- Auto-instrument HTTP frameworks, database clients, and message queues
|
|
119
|
+
- Add custom spans for business-critical operations
|
|
120
|
+
- Propagate trace context across service boundaries (W3C Trace Context)
|
|
121
|
+
- Add attributes (user ID, order ID, feature flag) to spans for filtering
|
|
122
|
+
|
|
123
|
+
**Logs** (detailed event records):
|
|
124
|
+
- Use structured JSON format, never unstructured text
|
|
125
|
+
- Include trace ID and span ID in every log for correlation
|
|
126
|
+
- Define consistent log levels (see [references/logging-patterns.md](references/logging-patterns.md))
|
|
127
|
+
- Redact sensitive data (passwords, tokens, PII) before logging
|
|
128
|
+
|
|
129
|
+
### Step 3: Set Up Alerting
|
|
130
|
+
|
|
131
|
+
Alerts should be actionable. Every alert should answer: "What happened? Is it urgent? What should I do?"
|
|
132
|
+
|
|
133
|
+
**Alert design rules:**
|
|
134
|
+
- Alert on SLO burn rate, not raw metric thresholds — this catches meaningful degradation while ignoring noise
|
|
135
|
+
- Every alert must link to a runbook
|
|
136
|
+
- Use severity levels: Page (wake someone up) vs Notify (review next business day)
|
|
137
|
+
- Set up multi-window burn rate alerts (fast burn = 1h window, slow burn = 6h window)
|
|
138
|
+
- Test alerts — an untested alert is an alert that won't fire when needed
|
|
139
|
+
|
|
140
|
+
See [references/logging-patterns.md](references/logging-patterns.md) for alerting patterns.
|
|
141
|
+
|
|
142
|
+
### Step 4: Design Dashboards
|
|
143
|
+
|
|
144
|
+
Dashboards should answer "is the system healthy?" in 5 seconds:
|
|
145
|
+
|
|
146
|
+
**Service overview dashboard:**
|
|
147
|
+
- SLO status and error budget remaining (the single most important panel)
|
|
148
|
+
- Request rate, error rate, and latency percentiles (P50, P95, P99)
|
|
149
|
+
- Active alerts
|
|
150
|
+
|
|
151
|
+
**Debug dashboard (per service):**
|
|
152
|
+
- Latency breakdown by dependency (database, cache, external APIs)
|
|
153
|
+
- Error rate by error type/code
|
|
154
|
+
- Resource utilization (CPU, memory, connections)
|
|
155
|
+
- Recent deployments overlaid on metrics
|
|
156
|
+
|
|
157
|
+
## Principles Applied
|
|
158
|
+
|
|
159
|
+
- **KISS**: Start with availability and latency SLIs. Add quality and freshness only when needed.
|
|
160
|
+
- **YAGNI**: Don't instrument everything on day one. Instrument the critical paths, add more when debugging reveals gaps.
|
|
161
|
+
- **DRY**: Use OpenTelemetry auto-instrumentation for common frameworks. Only add manual instrumentation for business-specific operations.
|
|
162
|
+
- **Functional Independence**: Each service owns its SLOs. Don't create SLOs that depend on another team's service — those become SLAs between teams.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "observability-design",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "We're launching a B2B SaaS API that processes invoices. We need to define SLOs before launch. Our customers expect the API to be fast and reliable — they integrate it into their accounting workflows. We use Express.js, PostgreSQL, and deploy on AWS ECS. Help us design our SLOs.",
|
|
7
|
+
"expected_output": "Should identify critical user journeys (submit invoice, retrieve invoice, list invoices), define SLIs as ratios (availability, latency), set appropriate SLO targets, calculate error budgets, define error budget policies, and produce an SLO document.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Identifies critical user journeys before defining metrics",
|
|
10
|
+
"Defines SLIs as good events / total events ratios",
|
|
11
|
+
"Sets availability SLO (e.g., 99.9%) with justification",
|
|
12
|
+
"Sets latency SLO with specific threshold (e.g., 99% < 500ms)",
|
|
13
|
+
"Calculates error budget in concrete terms (minutes or requests)",
|
|
14
|
+
"Defines error budget policy with escalating actions",
|
|
15
|
+
"Does NOT set SLOs at 99.99% without justifying the cost",
|
|
16
|
+
"Recommends measuring SLIs at the load balancer, not just app-side",
|
|
17
|
+
"Produces an SLO document using the template"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": 2,
|
|
22
|
+
"prompt": "We have a Node.js microservices architecture (5 services) and zero observability beyond console.log statements. Our CTO wants distributed tracing and proper monitoring. Where do we start?",
|
|
23
|
+
"expected_output": "Should recommend starting with OpenTelemetry auto-instrumentation on one service, then expanding. Should prioritize: structured logging → metrics → traces. Should not suggest instrumenting everything at once.",
|
|
24
|
+
"assertions": [
|
|
25
|
+
"Recommends starting with ONE service, not all five",
|
|
26
|
+
"Suggests OpenTelemetry auto-instrumentation as the quickest win",
|
|
27
|
+
"Prioritizes structured logging first (replacing console.log)",
|
|
28
|
+
"Recommends adding trace context to logs for correlation",
|
|
29
|
+
"Suggests an OTel Collector rather than direct-to-backend export",
|
|
30
|
+
"Does NOT recommend building custom instrumentation",
|
|
31
|
+
"Provides concrete Node.js OTel setup code",
|
|
32
|
+
"Suggests a backend for receiving telemetry (Jaeger, Grafana stack, etc.)",
|
|
33
|
+
"Applies KISS — not all 5 services on day one"
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"id": 3,
|
|
38
|
+
"prompt": "Our on-call engineers are getting 50+ alerts per week and most of them are noise. They're burned out and missing real incidents. How do we fix our alerting?",
|
|
39
|
+
"expected_output": "Should diagnose alert fatigue, recommend switching to SLO-based burn rate alerting, help classify alerts by severity, and suggest an alert review process.",
|
|
40
|
+
"assertions": [
|
|
41
|
+
"Identifies 50+/week as severe alert fatigue",
|
|
42
|
+
"Recommends auditing existing alerts (what fires, how often, what action was taken)",
|
|
43
|
+
"Suggests removing or silencing alerts that are never actionable",
|
|
44
|
+
"Recommends burn rate alerting instead of raw threshold alerting",
|
|
45
|
+
"Distinguishes between page-worthy (urgent) and ticket-worthy (can wait) alerts",
|
|
46
|
+
"Requires every alert to link to a runbook",
|
|
47
|
+
"Suggests a monthly alert review cadence",
|
|
48
|
+
"Does NOT just say 'raise the thresholds' — addresses root cause"
|
|
49
|
+
]
|
|
50
|
+
}
|
|
51
|
+
]
|
|
52
|
+
}
|