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,144 @@
|
|
|
1
|
+
# Code Review Checklist
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- Design principles checklist
|
|
5
|
+
- Security checklist
|
|
6
|
+
- Testing checklist
|
|
7
|
+
- Common patterns to flag
|
|
8
|
+
- Language-specific patterns
|
|
9
|
+
|
|
10
|
+
## Design Principles Checklist
|
|
11
|
+
|
|
12
|
+
### DRY (Don't Repeat Yourself)
|
|
13
|
+
Flag when you see:
|
|
14
|
+
- Same logic in multiple places (even if slightly different — the variations often indicate a missing abstraction)
|
|
15
|
+
- Copy-pasted code blocks with minor modifications
|
|
16
|
+
- Same validation rules implemented in multiple layers without a shared source
|
|
17
|
+
|
|
18
|
+
Don't flag:
|
|
19
|
+
- Similar code that represents genuinely different concepts (false DRY is worse than repetition)
|
|
20
|
+
- Test code that repeats setup (test readability trumps DRY)
|
|
21
|
+
|
|
22
|
+
### KISS (Keep It Simple, Stupid)
|
|
23
|
+
Flag when you see:
|
|
24
|
+
- Abstraction without a second consumer (premature abstraction)
|
|
25
|
+
- Design patterns used where a simple function would suffice
|
|
26
|
+
- Complex type gymnastics when a straightforward type would work
|
|
27
|
+
- Nested ternaries or complex boolean expressions that need a comment to understand
|
|
28
|
+
- Over-engineered configuration when values could be constants
|
|
29
|
+
|
|
30
|
+
### YAGNI (You Aren't Gonna Need It)
|
|
31
|
+
Flag when you see:
|
|
32
|
+
- Unused parameters, methods, classes, or exports
|
|
33
|
+
- Configuration for hypothetical future features
|
|
34
|
+
- Abstraction layers "in case we swap implementations"
|
|
35
|
+
- Generic solutions for a problem that currently has one case
|
|
36
|
+
- Comments like "we might need this later"
|
|
37
|
+
|
|
38
|
+
### SRP (Single Responsibility Principle)
|
|
39
|
+
Flag when you see:
|
|
40
|
+
- Functions longer than ~30 lines (not a hard rule, but a signal)
|
|
41
|
+
- Functions that do AND/THEN logic: "validate AND save AND notify"
|
|
42
|
+
- Classes with methods that use disjoint subsets of the class's fields
|
|
43
|
+
- Files that are the go-to place for "anything related to X"
|
|
44
|
+
- Mix of business logic and I/O in the same function
|
|
45
|
+
|
|
46
|
+
### Naming Quality
|
|
47
|
+
Flag when you see:
|
|
48
|
+
- Names that require reading the implementation to understand (`data`, `info`, `temp`, `result`, `handle`)
|
|
49
|
+
- Disinformation: names that imply something incorrect (`accountList` when it's actually a map, `hp` that could mean hypotenuse or hit points)
|
|
50
|
+
- Single-letter variables outside of tiny lambda/loop scopes
|
|
51
|
+
- Abbreviations that aren't universally understood in the domain
|
|
52
|
+
- Class names that aren't nouns or noun phrases (`ProcessData`, `ManageStuff`)
|
|
53
|
+
- Method names that aren't verb phrases (`data()` instead of `fetchData()`, `valid()` instead of `isValid()`)
|
|
54
|
+
- Inconsistent vocabulary: `fetch` in one place, `get` in another, `retrieve` in a third for the same concept
|
|
55
|
+
- Names that differ only in capitalization or by a number suffix (`user1`, `user2`)
|
|
56
|
+
|
|
57
|
+
Don't flag:
|
|
58
|
+
- Short names in tiny scopes where context is obvious (`i` in a 3-line loop, `e` in a catch block)
|
|
59
|
+
- Domain abbreviations the team has agreed on (`DTO`, `API`, `URL`)
|
|
60
|
+
|
|
61
|
+
### Function Size and Structure
|
|
62
|
+
Flag when you see:
|
|
63
|
+
- Functions that do more than one thing — look for sections separated by blank lines or comments, each doing a different job
|
|
64
|
+
- Mixed levels of abstraction in one function: high-level orchestration mixed with low-level bit manipulation or string parsing
|
|
65
|
+
- More than 2-3 function arguments — flag especially if several are the same type (easy to mix up)
|
|
66
|
+
- Side effects hidden behind the function name: a function called `checkPermission` that also logs analytics and updates a timestamp
|
|
67
|
+
- **Command-Query Separation violations**: A method that both changes state AND returns a value. Methods should either be commands (do something, return void) or queries (return something, change nothing). Mixing them surprises callers and makes code harder to reason about.
|
|
68
|
+
|
|
69
|
+
### Functional Independence
|
|
70
|
+
Flag when you see:
|
|
71
|
+
- Modules reaching into other modules' internals
|
|
72
|
+
- Shared mutable state between components
|
|
73
|
+
- Functions that require knowledge of the caller's context
|
|
74
|
+
- Temporal coupling (function A must be called before function B with nothing enforcing this)
|
|
75
|
+
|
|
76
|
+
## Security Checklist
|
|
77
|
+
|
|
78
|
+
- [ ] User input is validated/sanitized before use
|
|
79
|
+
- [ ] SQL queries use parameterized statements (no string concatenation)
|
|
80
|
+
- [ ] Auth checks are present on protected endpoints
|
|
81
|
+
- [ ] Sensitive data is not logged or exposed in error messages
|
|
82
|
+
- [ ] No hardcoded secrets, API keys, or credentials
|
|
83
|
+
- [ ] File paths are validated (no path traversal)
|
|
84
|
+
- [ ] Rate limiting considered for public endpoints
|
|
85
|
+
- [ ] CORS configuration is explicit, not wildcard
|
|
86
|
+
|
|
87
|
+
## Testing Checklist
|
|
88
|
+
|
|
89
|
+
- [ ] New behavior has corresponding tests
|
|
90
|
+
- [ ] Tests cover the happy path
|
|
91
|
+
- [ ] Tests cover at least one error/edge case
|
|
92
|
+
- [ ] Tests are independent (no shared mutable state)
|
|
93
|
+
- [ ] Test names describe the behavior being tested
|
|
94
|
+
- [ ] No logic in tests (no if/else, no loops)
|
|
95
|
+
- [ ] No tests that merely re-verify third-party library behavior (e.g. asserting a compression lib's magic bytes or compression ratio, or that an ORM persists a row) — tests target our own logic and our boundary with the library, not what the vendor's own tests already cover
|
|
96
|
+
- [ ] Mocks/stubs are used appropriately (not over-mocked)
|
|
97
|
+
- [ ] Integration tests exist for cross-boundary interactions
|
|
98
|
+
|
|
99
|
+
## Common Patterns to Flag
|
|
100
|
+
|
|
101
|
+
**Boolean blindness**: A function taking multiple boolean parameters. Prefer named options or enum types.
|
|
102
|
+
|
|
103
|
+
**Stringly typed**: Using strings where enums, constants, or types would prevent errors at compile time.
|
|
104
|
+
|
|
105
|
+
**Train wreck**: Long method chains like `user.getProfile().getAddress().getCity().toLowerCase()`. Each dot is a coupling point.
|
|
106
|
+
|
|
107
|
+
**Primitive obsession**: Passing raw strings/numbers when a domain type (EmailAddress, Money, UserId) would add safety and clarity.
|
|
108
|
+
|
|
109
|
+
**Feature envy**: A method that uses more data from another class than from its own. The method probably belongs in the other class.
|
|
110
|
+
|
|
111
|
+
**Shotgun surgery**: One logical change requires modifications across many files. Indicates poor encapsulation.
|
|
112
|
+
|
|
113
|
+
**Data clumps**: The same group of variables appears together in multiple places (e.g., `x, y, z` or `street, city, zip`). Extract them into a class or struct.
|
|
114
|
+
|
|
115
|
+
**Middle man**: A class that delegates almost everything to another class without adding value. Inline the delegation.
|
|
116
|
+
|
|
117
|
+
**Inappropriate intimacy**: Two classes that access each other's private details excessively. Restructure to restore proper boundaries.
|
|
118
|
+
|
|
119
|
+
## Comments: Good vs Bad
|
|
120
|
+
|
|
121
|
+
**Good comments** (keep them):
|
|
122
|
+
- Intent explanation: *why* a non-obvious approach was chosen
|
|
123
|
+
- Consequence warnings: "changing this format breaks the mobile parser"
|
|
124
|
+
- TODO with ticket reference: `// TODO(PROJ-123): replace with batch API when available`
|
|
125
|
+
- Legal or licensing notices required by policy
|
|
126
|
+
|
|
127
|
+
**Bad comments** (flag them):
|
|
128
|
+
- Redundant comments that restate the code: `// increment counter` above `counter++`
|
|
129
|
+
- Commented-out code — it lives in version control, delete it
|
|
130
|
+
- Journal comments ("added on 2024-01-15 by Alice") — git log handles this
|
|
131
|
+
- Mandated javadoc/docstrings on every function regardless of complexity — these go stale and add noise
|
|
132
|
+
- Misleading comments that don't match what the code does
|
|
133
|
+
|
|
134
|
+
**Rule**: If code needs a comment to explain *what* it does, refactor the code so it doesn't need one. Comments should explain *why*, not *what*.
|
|
135
|
+
|
|
136
|
+
## Language-Specific Patterns
|
|
137
|
+
|
|
138
|
+
These are loaded contextually based on the codebase language. If reviewing:
|
|
139
|
+
|
|
140
|
+
- **JavaScript/TypeScript**: Watch for `any` types, missing null checks, callback hell, missing async error handling, loose equality (== vs ===)
|
|
141
|
+
- **Python**: Watch for mutable default arguments, bare except clauses, circular imports, missing type hints on public APIs
|
|
142
|
+
- **Go**: Watch for ignored errors, goroutine leaks, missing context propagation, sync issues
|
|
143
|
+
- **Rust**: Watch for unnecessary clones, unwrap in non-test code, missing error context
|
|
144
|
+
- **Java**: Watch for null returns without Optional, checked exception abuse, mutable shared state
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: configuration-strategy
|
|
3
|
+
description: "Design environment configuration, secrets management, and feature-flag hierarchy for a service or feature. Triggers: config strategy, environment variables, .env, secrets management, feature flag, config hierarchy, config precedence, twelve-factor config, environment-specific settings."
|
|
4
|
+
model: haiku
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Configuration Strategy
|
|
9
|
+
|
|
10
|
+
Design configuration that is safe, auditable, and easy to change. Most configuration problems (hardcoded secrets, production config in dev, feature flags with no off-switch) come from not designing the system upfront.
|
|
11
|
+
|
|
12
|
+
## Step 1: Identify All Configuration Needed
|
|
13
|
+
|
|
14
|
+
List every piece of configuration the feature or service requires:
|
|
15
|
+
|
|
16
|
+
- **Service endpoints**: URLs for external APIs, internal services, databases
|
|
17
|
+
- **Credentials and secrets**: API keys, database passwords, signing keys, certificates
|
|
18
|
+
- **Behavior toggles**: Feature flags, A/B test parameters, rate limits, timeouts
|
|
19
|
+
- **Static config**: Timeouts, retry counts, pagination defaults, log levels
|
|
20
|
+
- **Environment-specific values**: Different database URLs for dev/staging/prod
|
|
21
|
+
|
|
22
|
+
Don't leave any implicit. "We'll hard-code the staging URL for now" is the start of a production incident.
|
|
23
|
+
|
|
24
|
+
## Step 2: Classify Each Configuration Item
|
|
25
|
+
|
|
26
|
+
For each item, determine:
|
|
27
|
+
|
|
28
|
+
**Sensitivity:**
|
|
29
|
+
- **Secret**: Must never appear in logs, code, or non-encrypted storage (API keys, passwords, tokens)
|
|
30
|
+
- **Sensitive**: Not a secret but not public (internal service URLs, customer IDs)
|
|
31
|
+
- **Non-sensitive**: Safe to log, safe in version control (log levels, timeouts, feature flag names)
|
|
32
|
+
|
|
33
|
+
**Mutability:**
|
|
34
|
+
- **Static**: Set at deploy time, doesn't change without a redeploy (database schema version, service name)
|
|
35
|
+
- **Runtime-mutable**: Can change without redeploy (feature flags, rate limits, A/B test parameters)
|
|
36
|
+
|
|
37
|
+
**Scope:**
|
|
38
|
+
- **Global**: Same value in all environments (timeout constants, algorithm parameters)
|
|
39
|
+
- **Environment-specific**: Different per env (database URLs, API endpoints, log levels)
|
|
40
|
+
- **Per-tenant/per-user**: Different per customer (feature entitlements, custom limits)
|
|
41
|
+
|
|
42
|
+
## Step 3: Design the Configuration Hierarchy
|
|
43
|
+
|
|
44
|
+
Based on classification, assign each item to the right storage:
|
|
45
|
+
|
|
46
|
+
| Storage | For | Examples |
|
|
47
|
+
|---------|-----|---------|
|
|
48
|
+
| Environment variables | Environment-specific non-secrets | DATABASE_URL, SERVICE_ENV, LOG_LEVEL |
|
|
49
|
+
| Secrets manager | All secrets | Database passwords, API keys, signing keys |
|
|
50
|
+
| Feature flag service | Runtime-mutable toggles | Feature flags, A/B variants, rollout percentages |
|
|
51
|
+
| Config file in repo | Non-sensitive static config | Timeout constants, retry policies, allowed values |
|
|
52
|
+
| Database (config table) | Per-tenant/per-user config | Customer-specific rate limits, feature entitlements |
|
|
53
|
+
|
|
54
|
+
**Hierarchy principle**: More specific overrides less specific. Per-tenant overrides environment which overrides global default.
|
|
55
|
+
|
|
56
|
+
See [references/config-patterns.md](references/config-patterns.md) for feature flag design patterns and secrets management tool guidance.
|
|
57
|
+
|
|
58
|
+
## Step 4: Plan Safe Config Rollout
|
|
59
|
+
|
|
60
|
+
Configuration changes can cause outages just like code changes. Plan rollout for each type:
|
|
61
|
+
|
|
62
|
+
**Secrets rotation:**
|
|
63
|
+
1. Generate new secret while old one remains valid
|
|
64
|
+
2. Deploy application with new secret
|
|
65
|
+
3. Verify application uses new secret correctly
|
|
66
|
+
4. Revoke old secret (after 24-hour overlap window)
|
|
67
|
+
|
|
68
|
+
**Feature flag rollout:**
|
|
69
|
+
1. Start at 0% — verify flag infrastructure works
|
|
70
|
+
2. Enable for internal users — catch obvious breakage
|
|
71
|
+
3. Enable for small percentage (5-10%) — monitor metrics
|
|
72
|
+
4. Ramp up gradually — verify metrics hold at each step
|
|
73
|
+
5. Full rollout — verify, then clean up the flag
|
|
74
|
+
|
|
75
|
+
**Environment variable changes:**
|
|
76
|
+
- New variables: set in target environment *before* deploying code that reads them
|
|
77
|
+
- Changed values: consider backward compatibility with old code during rolling deploys
|
|
78
|
+
- Removed variables: remove from code *before* removing from environment config
|
|
79
|
+
|
|
80
|
+
## Step 5: Audit Existing Code for Anti-patterns
|
|
81
|
+
|
|
82
|
+
Review the codebase for common configuration mistakes:
|
|
83
|
+
|
|
84
|
+
**Hardcoded values to find and fix:**
|
|
85
|
+
- IP addresses, hostnames, port numbers (search: `localhost`, `127.0.0.1`, regex for IP patterns)
|
|
86
|
+
- Credentials (search: `password`, `secret`, `api_key`, `token` in string literals)
|
|
87
|
+
- Environment-specific constants (search for strings that differ between environments)
|
|
88
|
+
- Magic numbers that should be configurable (search for hardcoded timeouts, limits, batch sizes)
|
|
89
|
+
|
|
90
|
+
**Config anti-patterns:**
|
|
91
|
+
- Feature flags that have been "on" everywhere for 6+ months (dead code risk — remove the flag)
|
|
92
|
+
- Config values read but never validated (add startup validation that fails fast on missing config)
|
|
93
|
+
- Different config loading paths for test vs production (leads to "works in tests but not prod")
|
|
94
|
+
- Secrets passed via command-line arguments (visible in process lists)
|
|
95
|
+
|
|
96
|
+
## Principles Applied
|
|
97
|
+
|
|
98
|
+
- **DRY**: Single source of truth for each config value. If the same value appears in multiple places, it will drift.
|
|
99
|
+
- **KISS**: Flat config beats deeply nested config. Environment variables beat custom config DSLs.
|
|
100
|
+
- **Least privilege**: Services should only have access to the secrets they need. Database credentials shouldn't be shared across services.
|
|
101
|
+
- **YAGNI**: Don't create config variables for things that will never change. Hard-code what's truly constant.
|
|
102
|
+
- **Fail fast**: Validate all required config on startup. A crash at startup is better than a mysterious failure 10 minutes in.
|
|
103
|
+
|
|
104
|
+
## Cross-Skill References
|
|
105
|
+
|
|
106
|
+
- `feature-planning` — decide which behaviors will be feature-flagged during planning, before implementation
|
|
107
|
+
- `security-audit` — review secrets handling and access control as part of security review
|
|
108
|
+
- `deployment-checklist` — verify all config is set before deploying
|
|
109
|
+
- `rollback-strategy` — feature flags are the simplest rollback mechanism; design them accordingly
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "configuration-strategy",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I'm adding a payment integration to our app. We'll need a Stripe API key, a webhook secret, and a flag to enable the new checkout flow for a gradual rollout. How should I manage this configuration?",
|
|
7
|
+
"expected_output": "Configuration strategy covering secrets (Stripe key, webhook secret → secrets manager), feature flag (new checkout → percentage rollout), and environment variable design with a phased rollout plan",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Identifies Stripe API key and webhook secret as secrets, recommends secrets manager not env var",
|
|
10
|
+
"Recommends feature flag for the checkout rollout, not a hard env var switch",
|
|
11
|
+
"Suggests percentage-based rollout for the feature flag",
|
|
12
|
+
"Warns against committing any credential to version control",
|
|
13
|
+
"Recommends startup validation to fail fast if secrets are missing",
|
|
14
|
+
"Notes different values needed for dev/staging/production"
|
|
15
|
+
]
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"id": 2,
|
|
19
|
+
"prompt": "Audit this Python file for configuration anti-patterns:\n\nDB_URL = 'postgresql://admin:password123@prod-db.internal:5432/myapp'\nAPI_TIMEOUT = 30\nDEBUG = True\nSTRIPE_KEY = 'sk_live_abc123xyz'\nRATELIMIT = 100",
|
|
20
|
+
"expected_output": "Identifies hardcoded credentials (DB_URL with password, STRIPE_KEY), hardcoded production hostname, and DEBUG=True as anti-patterns, with specific remediation for each",
|
|
21
|
+
"assertions": [
|
|
22
|
+
"Flags DB_URL as critical: contains hardcoded password and production hostname",
|
|
23
|
+
"Flags STRIPE_KEY as critical: live API key hardcoded in source",
|
|
24
|
+
"Flags DEBUG=True as problematic for production environments",
|
|
25
|
+
"Notes that API_TIMEOUT and RATELIMIT are acceptable as constants or could be made configurable",
|
|
26
|
+
"Recommends secrets manager or environment variables for the credentials",
|
|
27
|
+
"Recommends .env.example to document these variables without committing values"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"id": 3,
|
|
32
|
+
"prompt": "What's the best way to set up Terraform configuration for our infrastructure?",
|
|
33
|
+
"expected_output": "Recognizes this is an infrastructure-as-code question, not primarily a configuration strategy question — may address env var and secrets aspects but should note that IaC configuration patterns are covered by infrastructure-as-code skill",
|
|
34
|
+
"assertions": [
|
|
35
|
+
"Addresses the secrets/variable management aspects that overlap with config strategy",
|
|
36
|
+
"Recognizes that Terraform-specific patterns (workspaces, modules, state management) are better handled by the infrastructure-as-code skill",
|
|
37
|
+
"Does not attempt to be a comprehensive Terraform guide"
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
]
|
|
41
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# Configuration Patterns
|
|
2
|
+
|
|
3
|
+
## Feature Flag Patterns
|
|
4
|
+
|
|
5
|
+
### Boolean flags (on/off)
|
|
6
|
+
Simplest form. Use for new features, kill switches, and emergency toggles.
|
|
7
|
+
|
|
8
|
+
```python
|
|
9
|
+
if feature_flags.is_enabled("new_checkout_flow"):
|
|
10
|
+
return new_checkout()
|
|
11
|
+
return legacy_checkout()
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
**Cleanup discipline**: Set a removal date when creating the flag. Flags that are "on everywhere" for 6+ months are dead code. Schedule a cleanup sprint quarterly.
|
|
15
|
+
|
|
16
|
+
### Percentage rollout flags
|
|
17
|
+
For gradual rollouts. Route by user ID (not random) to ensure consistent experience per user.
|
|
18
|
+
|
|
19
|
+
```python
|
|
20
|
+
def should_show_feature(user_id: int, flag_name: str, percentage: int) -> bool:
|
|
21
|
+
# Consistent hash ensures same user always gets same result
|
|
22
|
+
bucket = hash(f"{flag_name}:{user_id}") % 100
|
|
23
|
+
return bucket < percentage
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Targeting flags
|
|
27
|
+
Enable for specific users, accounts, or segments. Common for:
|
|
28
|
+
- Beta testers / early access
|
|
29
|
+
- Internal employees
|
|
30
|
+
- Enterprise customers with specific entitlements
|
|
31
|
+
- A/B test groups
|
|
32
|
+
|
|
33
|
+
### Config flags (non-boolean)
|
|
34
|
+
For tunable parameters: rate limits, batch sizes, timeout values. Enable runtime tuning without redeploys.
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
RATE_LIMIT_PER_MINUTE = config.get_int("api_rate_limit_per_minute", default=100)
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Secrets Management
|
|
43
|
+
|
|
44
|
+
### What counts as a secret
|
|
45
|
+
- Database credentials (username + password)
|
|
46
|
+
- API keys and tokens (any key that grants access to an external service)
|
|
47
|
+
- Signing keys and certificates (JWT signing keys, TLS private keys, HMAC secrets)
|
|
48
|
+
- Encryption keys
|
|
49
|
+
- OAuth client secrets
|
|
50
|
+
|
|
51
|
+
**Not secrets** (but still environment-specific): Database hostnames, service URLs, log levels, feature flag names.
|
|
52
|
+
|
|
53
|
+
### Secrets manager tools
|
|
54
|
+
|
|
55
|
+
| Tool | Best for | Notes |
|
|
56
|
+
|------|----------|-------|
|
|
57
|
+
| AWS Secrets Manager | AWS-hosted apps | Native AWS integration, automatic rotation support |
|
|
58
|
+
| HashiCorp Vault | Multi-cloud, self-hosted | Most flexible; steeper ops overhead |
|
|
59
|
+
| GCP Secret Manager | GCP-hosted apps | Native GCP integration |
|
|
60
|
+
| Azure Key Vault | Azure-hosted apps | Native Azure integration |
|
|
61
|
+
| Doppler | Any cloud, simpler UX | Good for small teams, syncs to env vars |
|
|
62
|
+
|
|
63
|
+
### Accessing secrets at runtime
|
|
64
|
+
|
|
65
|
+
**Preferred: inject as environment variables at container/process startup**
|
|
66
|
+
```bash
|
|
67
|
+
# Kubernetes (via external-secrets operator or equivalent)
|
|
68
|
+
env:
|
|
69
|
+
- name: DATABASE_PASSWORD
|
|
70
|
+
valueFrom:
|
|
71
|
+
secretKeyRef:
|
|
72
|
+
name: db-credentials
|
|
73
|
+
key: password
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
**Acceptable: read from secrets manager SDK at startup, cache in memory**
|
|
77
|
+
```python
|
|
78
|
+
import boto3
|
|
79
|
+
secrets = boto3.client('secretsmanager')
|
|
80
|
+
DB_PASSWORD = secrets.get_secret_value(SecretId='prod/db/password')['SecretString']
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Never: hardcode in source, store in `.env` files committed to version control, pass via CLI argument**
|
|
84
|
+
|
|
85
|
+
### Startup validation pattern
|
|
86
|
+
Fail fast on missing config at application startup:
|
|
87
|
+
|
|
88
|
+
```python
|
|
89
|
+
def validate_config():
|
|
90
|
+
required = ['DATABASE_URL', 'API_KEY', 'JWT_SECRET']
|
|
91
|
+
missing = [key for key in required if not os.environ.get(key)]
|
|
92
|
+
if missing:
|
|
93
|
+
raise EnvironmentError(f"Missing required config: {', '.join(missing)}")
|
|
94
|
+
|
|
95
|
+
# Call before any application code runs
|
|
96
|
+
validate_config()
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Environment Hierarchy
|
|
102
|
+
|
|
103
|
+
### Typical environment chain
|
|
104
|
+
```
|
|
105
|
+
local dev → CI → staging → production
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Each environment should have a complete, independent configuration. Avoid sharing config between environments — shared config leads to "it works in staging because staging reads prod's config."
|
|
109
|
+
|
|
110
|
+
### Config loading priority (highest to lowest)
|
|
111
|
+
1. Environment variables (set by the runtime environment)
|
|
112
|
+
2. `.env.local` (local developer overrides, never committed)
|
|
113
|
+
3. `.env.[environment]` (environment-specific committed defaults, no secrets)
|
|
114
|
+
4. `.env` (shared defaults, no secrets)
|
|
115
|
+
5. Hard-coded defaults in application code
|
|
116
|
+
|
|
117
|
+
### What belongs in version control
|
|
118
|
+
|
|
119
|
+
| File | Purpose | Secrets? | Commit? |
|
|
120
|
+
|------|---------|---------|---------|
|
|
121
|
+
| `.env.example` | Documents all required vars with example values | No | Yes |
|
|
122
|
+
| `.env.development` | Dev defaults, no real secrets | No | Yes |
|
|
123
|
+
| `.env.staging` | Staging non-secrets | No | Yes |
|
|
124
|
+
| `.env` | Local overrides | No | No (add to .gitignore) |
|
|
125
|
+
| `.env.local` | Personal dev overrides | No | No |
|
|
126
|
+
| `.env.production` | Never — use secrets manager | — | Never |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Config Validation Patterns
|
|
131
|
+
|
|
132
|
+
### Type-safe config with validation
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// TypeScript example with runtime validation
|
|
136
|
+
const config = {
|
|
137
|
+
port: parseInt(process.env.PORT ?? '3000', 10),
|
|
138
|
+
databaseUrl: requireEnv('DATABASE_URL'),
|
|
139
|
+
jwtSecret: requireEnv('JWT_SECRET'),
|
|
140
|
+
logLevel: process.env.LOG_LEVEL ?? 'info',
|
|
141
|
+
featureFlagServiceUrl: process.env.FEATURE_FLAG_URL ?? null,
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
function requireEnv(key: string): string {
|
|
145
|
+
const value = process.env[key];
|
|
146
|
+
if (!value) throw new Error(`Required environment variable ${key} is not set`);
|
|
147
|
+
return value;
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Config schema documentation
|
|
152
|
+
|
|
153
|
+
Document every config variable. Keep this in sync with `.env.example`:
|
|
154
|
+
|
|
155
|
+
```
|
|
156
|
+
DATABASE_URL Required. PostgreSQL connection string.
|
|
157
|
+
Format: postgres://user:pass@host:port/dbname
|
|
158
|
+
JWT_SECRET Required. Min 32 chars. Used to sign auth tokens.
|
|
159
|
+
LOG_LEVEL Optional. Default: 'info'. Values: debug|info|warn|error
|
|
160
|
+
FEATURE_FLAG_URL Optional. LaunchDarkly SDK URL. Feature flags disabled if unset.
|
|
161
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: containerization
|
|
3
|
+
description: "Write production-grade Dockerfiles, docker-compose, and Kubernetes manifests following security and reliability best practices. Triggers: Dockerfile, docker-compose, containerize, Docker image, Kubernetes, k8s manifest, container, pod, deployment yaml, multi-stage build, docker build, image size, container security."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Containerization
|
|
9
|
+
|
|
10
|
+
Write production-quality container configurations — Dockerfiles, compose files, and Kubernetes manifests — that are secure, efficient, and reproducible.
|
|
11
|
+
|
|
12
|
+
## Workflow: Dockerfile
|
|
13
|
+
|
|
14
|
+
### Step 1: Understand the Application
|
|
15
|
+
|
|
16
|
+
Before writing a Dockerfile, establish:
|
|
17
|
+
|
|
18
|
+
- **Runtime**: Node.js, Python, Go, Java, etc. and specific version
|
|
19
|
+
- **Build process**: Does it need compilation, asset bundling, dependency installation?
|
|
20
|
+
- **Runtime dependencies**: System packages, native libraries
|
|
21
|
+
- **Entry point**: What command starts the application?
|
|
22
|
+
- **Configuration**: Environment variables, config files, secrets
|
|
23
|
+
|
|
24
|
+
### Step 2: Write the Dockerfile
|
|
25
|
+
|
|
26
|
+
Follow these principles in order of importance:
|
|
27
|
+
|
|
28
|
+
**1. Use multi-stage builds** — Separate build dependencies from the runtime image. Build artifacts in one stage, copy only what's needed to a slim final stage.
|
|
29
|
+
|
|
30
|
+
**2. Pin base image versions** — Never use `latest`. Use specific digests or version tags: `node:20.11-alpine3.19`, not `node:latest`.
|
|
31
|
+
|
|
32
|
+
**3. Minimize layers and image size** — Combine related RUN commands with `&&`. Use Alpine or distroless base images. Remove package manager caches after install.
|
|
33
|
+
|
|
34
|
+
**4. Order for cache efficiency** — Place infrequently changing instructions (system deps) before frequently changing ones (application code). Copy dependency manifests before source code.
|
|
35
|
+
|
|
36
|
+
**5. Run as non-root** — Create a dedicated user and switch to it. Never run production containers as root.
|
|
37
|
+
|
|
38
|
+
**6. Use .dockerignore** — Exclude node_modules, .git, .env, test files, docs from the build context.
|
|
39
|
+
|
|
40
|
+
Use [templates/dockerfile.md](templates/dockerfile.md) as a starting point for Node.js, Python, Go, and docker-compose configurations.
|
|
41
|
+
|
|
42
|
+
### Step 3: Validate
|
|
43
|
+
|
|
44
|
+
- [ ] Image builds successfully
|
|
45
|
+
- [ ] Image size is reasonable for the application type
|
|
46
|
+
- [ ] Container runs as non-root user
|
|
47
|
+
- [ ] No secrets baked into the image (check with `docker history`)
|
|
48
|
+
- [ ] Health check is defined
|
|
49
|
+
- [ ] .dockerignore excludes unnecessary files
|
|
50
|
+
|
|
51
|
+
## Workflow: Docker Compose (Local Development)
|
|
52
|
+
|
|
53
|
+
Design compose files that give developers a one-command local environment:
|
|
54
|
+
|
|
55
|
+
- All services defined (app, database, cache, queue)
|
|
56
|
+
- Volumes for hot-reload development
|
|
57
|
+
- Named volumes for data persistence across restarts
|
|
58
|
+
- Environment variables with sensible defaults via `.env.example`
|
|
59
|
+
- Health checks and dependency ordering (`depends_on` with `condition: service_healthy`)
|
|
60
|
+
- Port mappings that avoid common conflicts
|
|
61
|
+
|
|
62
|
+
See [references/dockerfile-patterns.md](references/dockerfile-patterns.md) for compose patterns.
|
|
63
|
+
|
|
64
|
+
## Workflow: Kubernetes Manifests
|
|
65
|
+
|
|
66
|
+
When creating K8s deployments:
|
|
67
|
+
|
|
68
|
+
1. **Define resource requests and limits** — Always. Without them, a single pod can starve the cluster.
|
|
69
|
+
2. **Configure health probes** — Liveness (is the process alive?), readiness (can it serve traffic?), startup (for slow-starting apps).
|
|
70
|
+
3. **Use ConfigMaps and Secrets** — Never hardcode configuration in manifests.
|
|
71
|
+
4. **Set pod disruption budgets** — For availability during upgrades.
|
|
72
|
+
5. **Use namespaces** — Isolate environments (dev, staging, prod) and teams.
|
|
73
|
+
6. **Define HPA** — Horizontal pod autoscaling based on CPU/memory or custom metrics.
|
|
74
|
+
|
|
75
|
+
## When to Use Helm or Kustomize
|
|
76
|
+
|
|
77
|
+
For multi-environment deployments or when using a deployment repo pattern, plain manifests become hard to manage. Choose based on your needs:
|
|
78
|
+
|
|
79
|
+
- **Plain manifests**: Single environment, few resources, no templating needed. Start here.
|
|
80
|
+
- **Kustomize**: Multiple environments with small differences (replicas, resource limits, image tags). Uses patches over a base — no templating language to learn.
|
|
81
|
+
- **Helm**: Complex deployments with many configurable parameters, or when you need to package charts for reuse. More powerful but more complexity.
|
|
82
|
+
|
|
83
|
+
See `deployment-repo` for organizing Helm charts and Kustomize overlays in a deployment repo, and `gitops-delivery` for using them with ArgoCD or Flux.
|
|
84
|
+
|
|
85
|
+
## Principles Applied
|
|
86
|
+
|
|
87
|
+
- **KISS**: Start with the simplest configuration that works. Single-stage Docker build before multi-stage. Docker Compose before Kubernetes.
|
|
88
|
+
- **DRY**: Use build args and env vars to parameterize, not duplicate Dockerfiles per environment.
|
|
89
|
+
- **Security by default**: Non-root, minimal image, no secrets in layers, read-only filesystem where possible.
|
|
90
|
+
- **YAGNI**: Don't add Kubernetes if Docker Compose serves your scale. Don't add Helm charts if plain manifests suffice.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "containerization",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Containerize my Express.js API. It uses Node 20, has a build step (TypeScript), connects to PostgreSQL and Redis, and needs to run in production on Kubernetes.",
|
|
7
|
+
"expected_output": "Should produce a multi-stage Dockerfile, .dockerignore, docker-compose for local dev, and basic K8s deployment manifest. All following security and efficiency best practices.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Uses multi-stage build (builder + production stages)",
|
|
10
|
+
"Pins Node version (not latest)",
|
|
11
|
+
"Copies package files before source code for cache efficiency",
|
|
12
|
+
"Uses npm ci (not npm install)",
|
|
13
|
+
"Runs as non-root user",
|
|
14
|
+
"Includes HEALTHCHECK",
|
|
15
|
+
"Creates .dockerignore excluding node_modules, .git, tests",
|
|
16
|
+
"Docker-compose includes PostgreSQL and Redis with health checks",
|
|
17
|
+
"K8s manifest includes resource limits, liveness/readiness probes"
|
|
18
|
+
]
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": 2,
|
|
22
|
+
"prompt": "Review this Dockerfile:\n\nFROM node:latest\nWORKDIR /app\nCOPY . .\nRUN npm install\nRUN npm run build\nENV DB_PASSWORD=mysecret123\nEXPOSE 3000\nCMD [\"node\", \"dist/index.js\"]",
|
|
23
|
+
"expected_output": "Should identify all issues: latest tag, no multi-stage, copies everything before deps, npm install not ci, secret in ENV, runs as root, no healthcheck, no .dockerignore.",
|
|
24
|
+
"assertions": [
|
|
25
|
+
"Flags 'latest' tag as unreproducible",
|
|
26
|
+
"Flags secret in ENV layer as critical security issue",
|
|
27
|
+
"Flags running as root",
|
|
28
|
+
"Recommends multi-stage build",
|
|
29
|
+
"Recommends copying package files before source",
|
|
30
|
+
"Recommends npm ci over npm install",
|
|
31
|
+
"Recommends adding HEALTHCHECK",
|
|
32
|
+
"Provides a corrected Dockerfile"
|
|
33
|
+
]
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
}
|