@hivehub/rulebook 3.4.2 → 4.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/.claude/commands/continue.md +33 -0
- package/.claude-plugin/marketplace.json +28 -29
- package/.claude-plugin/plugin.json +8 -8
- package/README.md +66 -144
- package/dist/agents/ralph-parser.d.ts +41 -1
- package/dist/agents/ralph-parser.d.ts.map +1 -1
- package/dist/agents/ralph-parser.js +202 -14
- package/dist/agents/ralph-parser.js.map +1 -1
- package/dist/cli/commands.d.ts +65 -0
- package/dist/cli/commands.d.ts.map +1 -1
- package/dist/cli/commands.js +837 -61
- package/dist/cli/commands.js.map +1 -1
- package/dist/core/agent-manager.d.ts +7 -0
- package/dist/core/agent-manager.d.ts.map +1 -1
- package/dist/core/agent-manager.js +150 -3
- package/dist/core/agent-manager.js.map +1 -1
- package/dist/core/claude-mcp.d.ts +17 -0
- package/dist/core/claude-mcp.d.ts.map +1 -1
- package/dist/core/claude-mcp.js +90 -6
- package/dist/core/claude-mcp.js.map +1 -1
- package/dist/core/config-manager.d.ts.map +1 -1
- package/dist/core/config-manager.js +40 -0
- package/dist/core/config-manager.js.map +1 -1
- package/dist/core/cursor-mdc-generator.d.ts +30 -0
- package/dist/core/cursor-mdc-generator.d.ts.map +1 -0
- package/dist/core/cursor-mdc-generator.js +98 -0
- package/dist/core/cursor-mdc-generator.js.map +1 -0
- package/dist/core/detector.d.ts +25 -1
- package/dist/core/detector.d.ts.map +1 -1
- package/dist/core/detector.js +321 -1
- package/dist/core/detector.js.map +1 -1
- package/dist/core/generator.d.ts +10 -0
- package/dist/core/generator.d.ts.map +1 -1
- package/dist/core/generator.js +177 -3
- package/dist/core/generator.js.map +1 -1
- package/dist/core/github-issues-importer.d.ts +82 -0
- package/dist/core/github-issues-importer.d.ts.map +1 -0
- package/dist/core/github-issues-importer.js +161 -0
- package/dist/core/github-issues-importer.js.map +1 -0
- package/dist/core/health-scorer.d.ts +39 -0
- package/dist/core/health-scorer.d.ts.map +1 -1
- package/dist/core/health-scorer.js +256 -13
- package/dist/core/health-scorer.js.map +1 -1
- package/dist/core/indexer/background-indexer.d.ts +27 -0
- package/dist/core/indexer/background-indexer.d.ts.map +1 -0
- package/dist/core/indexer/background-indexer.js +135 -0
- package/dist/core/indexer/background-indexer.js.map +1 -0
- package/dist/core/indexer/file-parser.d.ts +28 -0
- package/dist/core/indexer/file-parser.d.ts.map +1 -0
- package/dist/core/indexer/file-parser.js +171 -0
- package/dist/core/indexer/file-parser.js.map +1 -0
- package/dist/core/indexer/indexer-types.d.ts +35 -0
- package/dist/core/indexer/indexer-types.d.ts.map +1 -0
- package/dist/core/indexer/indexer-types.js +8 -0
- package/dist/core/indexer/indexer-types.js.map +1 -0
- package/dist/core/iteration-tracker.d.ts +28 -0
- package/dist/core/iteration-tracker.d.ts.map +1 -1
- package/dist/core/iteration-tracker.js +86 -0
- package/dist/core/iteration-tracker.js.map +1 -1
- package/dist/core/multi-tool-generator.d.ts +59 -0
- package/dist/core/multi-tool-generator.d.ts.map +1 -0
- package/dist/core/multi-tool-generator.js +157 -0
- package/dist/core/multi-tool-generator.js.map +1 -0
- package/dist/core/override-manager.d.ts +23 -0
- package/dist/core/override-manager.d.ts.map +1 -0
- package/dist/core/override-manager.js +82 -0
- package/dist/core/override-manager.js.map +1 -0
- package/dist/core/plans-manager.d.ts +46 -0
- package/dist/core/plans-manager.d.ts.map +1 -0
- package/dist/core/plans-manager.js +158 -0
- package/dist/core/plans-manager.js.map +1 -0
- package/dist/core/prd-generator.d.ts +12 -0
- package/dist/core/prd-generator.d.ts.map +1 -1
- package/dist/core/prd-generator.js +91 -2
- package/dist/core/prd-generator.js.map +1 -1
- package/dist/core/ralph-manager.d.ts +47 -1
- package/dist/core/ralph-manager.d.ts.map +1 -1
- package/dist/core/ralph-manager.js +107 -0
- package/dist/core/ralph-manager.js.map +1 -1
- package/dist/core/ralph-parallel.d.ts +55 -0
- package/dist/core/ralph-parallel.d.ts.map +1 -0
- package/dist/core/ralph-parallel.js +201 -0
- package/dist/core/ralph-parallel.js.map +1 -0
- package/dist/core/ralph-plan-checkpoint.d.ts +58 -0
- package/dist/core/ralph-plan-checkpoint.d.ts.map +1 -0
- package/dist/core/ralph-plan-checkpoint.js +154 -0
- package/dist/core/ralph-plan-checkpoint.js.map +1 -0
- package/dist/core/ralph-scripts.d.ts +12 -0
- package/dist/core/ralph-scripts.d.ts.map +1 -0
- package/dist/core/ralph-scripts.js +49 -0
- package/dist/core/ralph-scripts.js.map +1 -0
- package/dist/core/review-manager.d.ts +74 -0
- package/dist/core/review-manager.d.ts.map +1 -0
- package/dist/core/review-manager.js +371 -0
- package/dist/core/review-manager.js.map +1 -0
- package/dist/index.js +94 -2
- package/dist/index.js.map +1 -1
- package/dist/mcp/rulebook-server.d.ts.map +1 -1
- package/dist/mcp/rulebook-server.js +117 -8
- package/dist/mcp/rulebook-server.js.map +1 -1
- package/dist/memory/memory-manager.d.ts +4 -1
- package/dist/memory/memory-manager.d.ts.map +1 -1
- package/dist/memory/memory-manager.js +33 -4
- package/dist/memory/memory-manager.js.map +1 -1
- package/dist/memory/memory-search.d.ts +2 -2
- package/dist/memory/memory-search.d.ts.map +1 -1
- package/dist/memory/memory-search.js +19 -0
- package/dist/memory/memory-search.js.map +1 -1
- package/dist/memory/memory-store.d.ts +13 -0
- package/dist/memory/memory-store.d.ts.map +1 -1
- package/dist/memory/memory-store.js +92 -1
- package/dist/memory/memory-store.js.map +1 -1
- package/dist/memory/memory-types.d.ts +15 -0
- package/dist/memory/memory-types.d.ts.map +1 -1
- package/dist/types.d.ts +55 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/agents/implementer.md +35 -0
- package/templates/agents/researcher.md +34 -0
- package/templates/agents/team-lead.md +34 -0
- package/templates/agents/tester.md +42 -0
- package/templates/ci/rulebook-review.yml +26 -0
- package/templates/commands/rulebook-task-archive.md +24 -0
- package/templates/core/AGENTS_LEAN.md +25 -0
- package/templates/core/AGENTS_OVERRIDE.md +16 -0
- package/templates/core/MULTI_AGENT.md +74 -0
- package/templates/core/PLANS.md +28 -0
- package/templates/core/RALPH.md +45 -4
- package/templates/core/RULEBOOK.md +42 -0
- package/templates/ides/CONTINUE_RULES.md +16 -0
- package/templates/ides/COPILOT_INSTRUCTIONS.md +23 -0
- package/templates/ides/GEMINI_RULES.md +17 -0
- package/templates/ides/WINDSURF_RULES.md +14 -0
- package/templates/ides/cursor-mdc/go.mdc +24 -0
- package/templates/ides/cursor-mdc/python.mdc +24 -0
- package/templates/ides/cursor-mdc/quality.mdc +25 -0
- package/templates/ides/cursor-mdc/ralph.mdc +39 -0
- package/templates/ides/cursor-mdc/rulebook.mdc +38 -0
- package/templates/ides/cursor-mdc/rust.mdc +24 -0
- package/templates/ides/cursor-mdc/typescript.mdc +25 -0
- package/templates/modules/sequential-thinking.md +42 -0
- package/templates/ralph/ralph-history.bat +4 -0
- package/templates/ralph/ralph-history.sh +5 -0
- package/templates/ralph/ralph-init.bat +5 -0
- package/templates/ralph/ralph-init.sh +5 -0
- package/templates/ralph/ralph-pause.bat +5 -0
- package/templates/ralph/ralph-pause.sh +5 -0
- package/templates/ralph/ralph-run.bat +5 -0
- package/templates/ralph/ralph-run.sh +5 -0
- package/templates/ralph/ralph-status.bat +4 -0
- package/templates/ralph/ralph-status.sh +5 -0
- package/templates/services/DATADOG.md +26 -0
- package/templates/services/DOCKER.md +124 -0
- package/templates/services/DOCKER_COMPOSE.md +168 -0
- package/templates/services/HELM.md +194 -0
- package/templates/services/KUBERNETES.md +208 -0
- package/templates/services/OPENTELEMETRY.md +25 -0
- package/templates/services/PINO.md +24 -0
- package/templates/services/PROMETHEUS.md +33 -0
- package/templates/services/SENTRY.md +23 -0
- package/templates/services/WINSTON.md +30 -0
- package/dist/core/openspec-manager.d.ts +0 -133
- package/dist/core/openspec-manager.d.ts.map +0 -1
- package/dist/core/openspec-manager.js +0 -596
- package/dist/core/openspec-manager.js.map +0 -1
- package/dist/core/openspec-migrator.d.ts +0 -27
- package/dist/core/openspec-migrator.d.ts.map +0 -1
- package/dist/core/openspec-migrator.js +0 -262
- package/dist/core/openspec-migrator.js.map +0 -1
- package/dist/core/test-task-manager.d.ts +0 -49
- package/dist/core/test-task-manager.d.ts.map +0 -1
- package/dist/core/test-task-manager.js +0 -121
- package/dist/core/test-task-manager.js.map +0 -1
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
<!-- DOCKER:START -->
|
|
2
|
+
# Docker Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Follow these Docker best practices for all container builds.
|
|
5
|
+
|
|
6
|
+
## Build Patterns
|
|
7
|
+
|
|
8
|
+
### Multi-Stage Builds
|
|
9
|
+
Use multi-stage builds to minimize final image size and separate build-time dependencies from runtime:
|
|
10
|
+
|
|
11
|
+
```dockerfile
|
|
12
|
+
FROM node:20-alpine AS builder
|
|
13
|
+
WORKDIR /app
|
|
14
|
+
COPY package*.json ./
|
|
15
|
+
RUN npm ci
|
|
16
|
+
COPY . .
|
|
17
|
+
RUN npm run build
|
|
18
|
+
|
|
19
|
+
FROM node:20-alpine AS runtime
|
|
20
|
+
RUN adduser -D appuser
|
|
21
|
+
USER appuser
|
|
22
|
+
WORKDIR /app
|
|
23
|
+
COPY --from=builder /app/dist ./dist
|
|
24
|
+
COPY --from=builder /app/node_modules ./node_modules
|
|
25
|
+
COPY --from=builder /app/package.json ./
|
|
26
|
+
HEALTHCHECK --interval=30s --timeout=3s CMD node -e "require('http').get('http://localhost:3000/health', (r) => { process.exit(r.statusCode === 200 ? 0 : 1) })"
|
|
27
|
+
CMD ["node", "dist/index.js"]
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Base Image Selection
|
|
31
|
+
- Pin base image versions: `node:20-alpine` not `node:latest`
|
|
32
|
+
- Prefer `-alpine` or `-slim` variants for smaller images
|
|
33
|
+
- Use official images from Docker Hub verified publishers
|
|
34
|
+
|
|
35
|
+
## Security Requirements
|
|
36
|
+
|
|
37
|
+
### Non-Root User
|
|
38
|
+
ALL containers MUST run as a non-root user:
|
|
39
|
+
```dockerfile
|
|
40
|
+
RUN adduser -D appuser
|
|
41
|
+
USER appuser
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Secrets
|
|
45
|
+
- NEVER copy secrets (`.env`, credentials, keys) into image layers
|
|
46
|
+
- Use Docker secrets or runtime environment variables instead
|
|
47
|
+
- Scan images with `docker scout cves` or `trivy image` before pushing
|
|
48
|
+
- Add `--no-cache` to package install commands to reduce attack surface
|
|
49
|
+
|
|
50
|
+
### Image Scanning
|
|
51
|
+
```bash
|
|
52
|
+
# Docker Scout (built-in)
|
|
53
|
+
docker scout cves <image>
|
|
54
|
+
|
|
55
|
+
# Trivy
|
|
56
|
+
trivy image <image>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Required Instructions
|
|
60
|
+
|
|
61
|
+
### HEALTHCHECK
|
|
62
|
+
ALL production images MUST include a HEALTHCHECK:
|
|
63
|
+
```dockerfile
|
|
64
|
+
HEALTHCHECK --interval=30s --timeout=3s --start-period=10s --retries=3 \
|
|
65
|
+
CMD curl -f http://localhost:3000/health || exit 1
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### .dockerignore Requirements
|
|
69
|
+
Every Docker project MUST have a `.dockerignore` file containing at minimum:
|
|
70
|
+
```
|
|
71
|
+
.git
|
|
72
|
+
node_modules
|
|
73
|
+
dist
|
|
74
|
+
coverage
|
|
75
|
+
*.log
|
|
76
|
+
.env*
|
|
77
|
+
.DS_Store
|
|
78
|
+
*.md
|
|
79
|
+
.vscode
|
|
80
|
+
.idea
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Common Patterns
|
|
84
|
+
|
|
85
|
+
### Layer Caching
|
|
86
|
+
Order Dockerfile instructions from least-changing to most-changing:
|
|
87
|
+
```dockerfile
|
|
88
|
+
# 1. Base image (rarely changes)
|
|
89
|
+
FROM node:20-alpine
|
|
90
|
+
|
|
91
|
+
# 2. System dependencies (changes rarely)
|
|
92
|
+
RUN apk add --no-cache curl
|
|
93
|
+
|
|
94
|
+
# 3. Package files (changes when deps change)
|
|
95
|
+
COPY package*.json ./
|
|
96
|
+
RUN npm ci --only=production
|
|
97
|
+
|
|
98
|
+
# 4. Application code (changes frequently)
|
|
99
|
+
COPY . .
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Production Optimization
|
|
103
|
+
```dockerfile
|
|
104
|
+
# Use npm ci for deterministic installs
|
|
105
|
+
RUN npm ci --only=production
|
|
106
|
+
|
|
107
|
+
# Remove unnecessary files
|
|
108
|
+
RUN rm -rf /tmp/* /var/cache/apk/*
|
|
109
|
+
|
|
110
|
+
# Set NODE_ENV
|
|
111
|
+
ENV NODE_ENV=production
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Best Practices
|
|
115
|
+
|
|
116
|
+
- Use `.dockerignore` to exclude unnecessary files from build context
|
|
117
|
+
- One process per container (do not run multiple services in one container)
|
|
118
|
+
- Use `COPY` over `ADD` unless extracting archives
|
|
119
|
+
- Combine RUN commands to reduce layers: `RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*`
|
|
120
|
+
- Set explicit `WORKDIR` instead of `RUN cd`
|
|
121
|
+
- Use `EXPOSE` to document listening ports
|
|
122
|
+
- Tag images with semantic versions, not just `latest`
|
|
123
|
+
|
|
124
|
+
<!-- DOCKER:END -->
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
<!-- DOCKER_COMPOSE:START -->
|
|
2
|
+
# Docker Compose Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Follow these Docker Compose best practices for local development and multi-container orchestration.
|
|
5
|
+
|
|
6
|
+
## Version and Structure
|
|
7
|
+
|
|
8
|
+
### File Organization
|
|
9
|
+
- Use `docker-compose.yml` for base configuration
|
|
10
|
+
- Use `docker-compose.override.yml` for local development overrides
|
|
11
|
+
- Use `docker-compose.prod.yml` for production-specific settings
|
|
12
|
+
- Do NOT commit secrets in `docker-compose.yml` — use `.env` files
|
|
13
|
+
|
|
14
|
+
### Compose File
|
|
15
|
+
```yaml
|
|
16
|
+
services:
|
|
17
|
+
app:
|
|
18
|
+
build:
|
|
19
|
+
context: .
|
|
20
|
+
dockerfile: Dockerfile
|
|
21
|
+
target: runtime
|
|
22
|
+
env_file: [.env]
|
|
23
|
+
ports:
|
|
24
|
+
- "3000:3000"
|
|
25
|
+
depends_on:
|
|
26
|
+
db:
|
|
27
|
+
condition: service_healthy
|
|
28
|
+
healthcheck:
|
|
29
|
+
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
|
30
|
+
interval: 30s
|
|
31
|
+
timeout: 3s
|
|
32
|
+
retries: 3
|
|
33
|
+
start_period: 10s
|
|
34
|
+
deploy:
|
|
35
|
+
resources:
|
|
36
|
+
limits:
|
|
37
|
+
memory: 512M
|
|
38
|
+
cpus: "0.5"
|
|
39
|
+
restart: unless-stopped
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Required Fields Per Service
|
|
43
|
+
|
|
44
|
+
### Health Checks
|
|
45
|
+
ALL services MUST define a healthcheck:
|
|
46
|
+
```yaml
|
|
47
|
+
healthcheck:
|
|
48
|
+
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
|
|
49
|
+
interval: 30s
|
|
50
|
+
timeout: 3s
|
|
51
|
+
retries: 3
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Resource Limits
|
|
55
|
+
ALL services SHOULD define resource limits for production-like environments:
|
|
56
|
+
```yaml
|
|
57
|
+
deploy:
|
|
58
|
+
resources:
|
|
59
|
+
limits:
|
|
60
|
+
memory: 512M
|
|
61
|
+
cpus: "0.5"
|
|
62
|
+
reservations:
|
|
63
|
+
memory: 128M
|
|
64
|
+
cpus: "0.25"
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Restart Policy
|
|
68
|
+
```yaml
|
|
69
|
+
restart: unless-stopped
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Named Volumes
|
|
73
|
+
Use named volumes (not bind mounts) for persistent data:
|
|
74
|
+
```yaml
|
|
75
|
+
volumes:
|
|
76
|
+
postgres_data:
|
|
77
|
+
redis_data:
|
|
78
|
+
|
|
79
|
+
services:
|
|
80
|
+
db:
|
|
81
|
+
volumes:
|
|
82
|
+
- postgres_data:/var/lib/postgresql/data
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Environment Variables
|
|
86
|
+
|
|
87
|
+
### Configuration
|
|
88
|
+
- Use `.env` file: `env_file: [.env]`
|
|
89
|
+
- Never hardcode credentials in docker-compose.yml
|
|
90
|
+
- Document all required environment variables in README or `.env.example`
|
|
91
|
+
|
|
92
|
+
### .env.example Pattern
|
|
93
|
+
```bash
|
|
94
|
+
# Database
|
|
95
|
+
DB_HOST=localhost
|
|
96
|
+
DB_PORT=5432
|
|
97
|
+
DB_NAME=myapp
|
|
98
|
+
DB_USER=myuser
|
|
99
|
+
DB_PASSWORD=changeme
|
|
100
|
+
|
|
101
|
+
# Redis
|
|
102
|
+
REDIS_URL=redis://localhost:6379
|
|
103
|
+
|
|
104
|
+
# Application
|
|
105
|
+
NODE_ENV=development
|
|
106
|
+
PORT=3000
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Networking
|
|
110
|
+
|
|
111
|
+
### Service Communication
|
|
112
|
+
- Services on the same network communicate by service name
|
|
113
|
+
- Use explicit networks for isolation:
|
|
114
|
+
```yaml
|
|
115
|
+
networks:
|
|
116
|
+
frontend:
|
|
117
|
+
backend:
|
|
118
|
+
|
|
119
|
+
services:
|
|
120
|
+
app:
|
|
121
|
+
networks: [frontend, backend]
|
|
122
|
+
db:
|
|
123
|
+
networks: [backend]
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Common Patterns
|
|
127
|
+
|
|
128
|
+
### Development Setup
|
|
129
|
+
```yaml
|
|
130
|
+
services:
|
|
131
|
+
app:
|
|
132
|
+
build: .
|
|
133
|
+
volumes:
|
|
134
|
+
- .:/app
|
|
135
|
+
- /app/node_modules
|
|
136
|
+
environment:
|
|
137
|
+
- NODE_ENV=development
|
|
138
|
+
command: npm run dev
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Database with Init Scripts
|
|
142
|
+
```yaml
|
|
143
|
+
services:
|
|
144
|
+
db:
|
|
145
|
+
image: postgres:16-alpine
|
|
146
|
+
environment:
|
|
147
|
+
POSTGRES_DB: myapp
|
|
148
|
+
POSTGRES_USER: myuser
|
|
149
|
+
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
150
|
+
volumes:
|
|
151
|
+
- postgres_data:/var/lib/postgresql/data
|
|
152
|
+
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
|
|
153
|
+
healthcheck:
|
|
154
|
+
test: ["CMD-SHELL", "pg_isready -U myuser"]
|
|
155
|
+
interval: 10s
|
|
156
|
+
retries: 5
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Best Practices
|
|
160
|
+
|
|
161
|
+
- Use `depends_on` with `condition: service_healthy` for startup ordering
|
|
162
|
+
- Pin image versions (e.g., `postgres:16-alpine`, not `postgres:latest`)
|
|
163
|
+
- Keep compose files DRY with YAML anchors or extension fields (`x-common`)
|
|
164
|
+
- Use `docker compose up --build` to rebuild images after code changes
|
|
165
|
+
- Run `docker compose down -v` to clean up volumes during development
|
|
166
|
+
- Separate concerns: one service per container
|
|
167
|
+
|
|
168
|
+
<!-- DOCKER_COMPOSE:END -->
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
<!-- HELM:START -->
|
|
2
|
+
# Helm Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Follow these Helm best practices for Kubernetes package management.
|
|
5
|
+
|
|
6
|
+
## Chart Structure
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
charts/<name>/
|
|
10
|
+
├── Chart.yaml # Chart metadata (required)
|
|
11
|
+
├── values.yaml # Default values (required)
|
|
12
|
+
├── templates/ # Kubernetes manifests
|
|
13
|
+
│ ├── deployment.yaml
|
|
14
|
+
│ ├── service.yaml
|
|
15
|
+
│ ├── ingress.yaml
|
|
16
|
+
│ ├── configmap.yaml
|
|
17
|
+
│ ├── secret.yaml
|
|
18
|
+
│ ├── hpa.yaml
|
|
19
|
+
│ ├── _helpers.tpl # Template helpers
|
|
20
|
+
│ ├── NOTES.txt # Post-install notes
|
|
21
|
+
│ └── tests/
|
|
22
|
+
│ └── test-connection.yaml
|
|
23
|
+
├── charts/ # Chart dependencies
|
|
24
|
+
└── .helmignore # Files to exclude from packaging
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Chart.yaml Requirements
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
apiVersion: v2
|
|
31
|
+
name: my-app
|
|
32
|
+
description: A Helm chart for my application
|
|
33
|
+
type: application
|
|
34
|
+
version: 1.0.0 # Chart version (bump on every change)
|
|
35
|
+
appVersion: "1.0.0" # Application version (keep in sync)
|
|
36
|
+
maintainers:
|
|
37
|
+
- name: team-name
|
|
38
|
+
email: team@example.com
|
|
39
|
+
dependencies:
|
|
40
|
+
- name: postgresql
|
|
41
|
+
version: "12.x.x"
|
|
42
|
+
repository: "https://charts.bitnami.com/bitnami"
|
|
43
|
+
condition: postgresql.enabled
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## values.yaml Requirements
|
|
47
|
+
|
|
48
|
+
- Document every value with a comment
|
|
49
|
+
- Set sensible production defaults
|
|
50
|
+
- Never hardcode image tags
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
# -- Number of replicas
|
|
54
|
+
replicaCount: 3
|
|
55
|
+
|
|
56
|
+
image:
|
|
57
|
+
# -- Container image repository
|
|
58
|
+
repository: my-registry/my-app
|
|
59
|
+
# -- Image pull policy
|
|
60
|
+
pullPolicy: IfNotPresent
|
|
61
|
+
# -- Image tag (defaults to chart appVersion)
|
|
62
|
+
tag: ""
|
|
63
|
+
|
|
64
|
+
# -- Resource requests and limits
|
|
65
|
+
resources:
|
|
66
|
+
requests:
|
|
67
|
+
memory: "128Mi"
|
|
68
|
+
cpu: "100m"
|
|
69
|
+
limits:
|
|
70
|
+
memory: "512Mi"
|
|
71
|
+
cpu: "500m"
|
|
72
|
+
|
|
73
|
+
# -- Enable/disable autoscaling
|
|
74
|
+
autoscaling:
|
|
75
|
+
enabled: true
|
|
76
|
+
minReplicas: 2
|
|
77
|
+
maxReplicas: 10
|
|
78
|
+
targetCPUUtilizationPercentage: 80
|
|
79
|
+
|
|
80
|
+
# -- Service configuration
|
|
81
|
+
service:
|
|
82
|
+
type: ClusterIP
|
|
83
|
+
port: 80
|
|
84
|
+
|
|
85
|
+
# -- Ingress configuration
|
|
86
|
+
ingress:
|
|
87
|
+
enabled: false
|
|
88
|
+
className: ""
|
|
89
|
+
annotations: {}
|
|
90
|
+
hosts:
|
|
91
|
+
- host: my-app.example.com
|
|
92
|
+
paths:
|
|
93
|
+
- path: /
|
|
94
|
+
pathType: ImplementationSpecific
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Template Best Practices
|
|
98
|
+
|
|
99
|
+
### _helpers.tpl
|
|
100
|
+
Define reusable template fragments:
|
|
101
|
+
```yaml
|
|
102
|
+
{{- define "chart.fullname" -}}
|
|
103
|
+
{{- if .Values.fullnameOverride }}
|
|
104
|
+
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
|
105
|
+
{{- else }}
|
|
106
|
+
{{- $name := default .Chart.Name .Values.nameOverride }}
|
|
107
|
+
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
|
108
|
+
{{- end }}
|
|
109
|
+
{{- end }}
|
|
110
|
+
|
|
111
|
+
{{- define "chart.labels" -}}
|
|
112
|
+
helm.sh/chart: {{ include "chart.chart" . }}
|
|
113
|
+
app.kubernetes.io/name: {{ include "chart.name" . }}
|
|
114
|
+
app.kubernetes.io/instance: {{ .Release.Name }}
|
|
115
|
+
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
|
116
|
+
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
|
117
|
+
{{- end }}
|
|
118
|
+
|
|
119
|
+
{{- define "chart.selectorLabels" -}}
|
|
120
|
+
app.kubernetes.io/name: {{ include "chart.name" . }}
|
|
121
|
+
app.kubernetes.io/instance: {{ .Release.Name }}
|
|
122
|
+
{{- end }}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Template Patterns
|
|
126
|
+
- Use `{{ include "chart.fullname" . }}` for consistent naming
|
|
127
|
+
- Always add labels: `{{ include "chart.labels" . | nindent 4 }}`
|
|
128
|
+
- Use `{{ .Values.x | default "fallback" }}` for optional values
|
|
129
|
+
- Use `{{- with .Values.x }}` blocks for conditional sections
|
|
130
|
+
- Quote all string values: `{{ .Values.image.tag | quote }}`
|
|
131
|
+
|
|
132
|
+
## Versioning
|
|
133
|
+
|
|
134
|
+
- Bump `Chart.yaml` version on every change (semver: MAJOR.MINOR.PATCH)
|
|
135
|
+
- Keep `appVersion` in sync with the application version
|
|
136
|
+
- Use `helm dependency update` after changing dependencies
|
|
137
|
+
- Tag releases in version control matching chart version
|
|
138
|
+
|
|
139
|
+
## Linting and Validation
|
|
140
|
+
|
|
141
|
+
Run these checks before every commit:
|
|
142
|
+
```bash
|
|
143
|
+
# Lint the chart
|
|
144
|
+
helm lint charts/my-app/
|
|
145
|
+
|
|
146
|
+
# Render templates locally
|
|
147
|
+
helm template my-release charts/my-app/ --values values-dev.yaml
|
|
148
|
+
|
|
149
|
+
# Validate rendered templates
|
|
150
|
+
helm template my-release charts/my-app/ | kubeval --strict
|
|
151
|
+
|
|
152
|
+
# Dry-run against cluster
|
|
153
|
+
helm install my-release charts/my-app/ --dry-run --debug
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Common Patterns
|
|
157
|
+
|
|
158
|
+
### Environment-Specific Values
|
|
159
|
+
```bash
|
|
160
|
+
# Development
|
|
161
|
+
helm install my-app charts/my-app/ -f values-dev.yaml
|
|
162
|
+
|
|
163
|
+
# Staging
|
|
164
|
+
helm install my-app charts/my-app/ -f values-staging.yaml
|
|
165
|
+
|
|
166
|
+
# Production
|
|
167
|
+
helm install my-app charts/my-app/ -f values-prod.yaml
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Secrets Management
|
|
171
|
+
```yaml
|
|
172
|
+
# Use external-secrets or sealed-secrets
|
|
173
|
+
# Never store plaintext secrets in values.yaml
|
|
174
|
+
externalSecrets:
|
|
175
|
+
enabled: true
|
|
176
|
+
secretStore: aws-secrets-manager
|
|
177
|
+
data:
|
|
178
|
+
- secretKey: DATABASE_URL
|
|
179
|
+
remoteRef:
|
|
180
|
+
key: /myapp/database-url
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Best Practices
|
|
184
|
+
|
|
185
|
+
- Use `helm create` to scaffold new charts with best-practice defaults
|
|
186
|
+
- Include chart tests in `templates/tests/`
|
|
187
|
+
- Document all values in `values.yaml` with comments
|
|
188
|
+
- Use `.helmignore` to exclude development files from chart packages
|
|
189
|
+
- Pin dependency versions (avoid `*` or floating ranges)
|
|
190
|
+
- Use `helm diff` plugin to preview changes before upgrading
|
|
191
|
+
- Store charts in a Helm repository (ChartMuseum, Harbor, OCI registry)
|
|
192
|
+
- Run `helm lint` in CI/CD pipeline
|
|
193
|
+
|
|
194
|
+
<!-- HELM:END -->
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
<!-- KUBERNETES:START -->
|
|
2
|
+
# Kubernetes Instructions
|
|
3
|
+
|
|
4
|
+
**CRITICAL**: Follow these Kubernetes best practices for all cluster deployments.
|
|
5
|
+
|
|
6
|
+
## Resource Requirements
|
|
7
|
+
|
|
8
|
+
ALL Deployments MUST define resource requests and limits:
|
|
9
|
+
```yaml
|
|
10
|
+
resources:
|
|
11
|
+
requests:
|
|
12
|
+
memory: "128Mi"
|
|
13
|
+
cpu: "100m"
|
|
14
|
+
limits:
|
|
15
|
+
memory: "512Mi"
|
|
16
|
+
cpu: "500m"
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Omitting resource limits causes unbounded resource consumption and can destabilize the cluster.
|
|
20
|
+
|
|
21
|
+
## Health Probes
|
|
22
|
+
|
|
23
|
+
ALL Deployments MUST define both readiness and liveness probes:
|
|
24
|
+
```yaml
|
|
25
|
+
readinessProbe:
|
|
26
|
+
httpGet:
|
|
27
|
+
path: /health
|
|
28
|
+
port: 3000
|
|
29
|
+
initialDelaySeconds: 5
|
|
30
|
+
periodSeconds: 10
|
|
31
|
+
failureThreshold: 3
|
|
32
|
+
livenessProbe:
|
|
33
|
+
httpGet:
|
|
34
|
+
path: /health
|
|
35
|
+
port: 3000
|
|
36
|
+
initialDelaySeconds: 15
|
|
37
|
+
periodSeconds: 20
|
|
38
|
+
failureThreshold: 3
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Probe Guidelines
|
|
42
|
+
- **readinessProbe**: Gates traffic to the pod. Use a lightweight endpoint
|
|
43
|
+
- **livenessProbe**: Restarts the pod if unhealthy. Set `initialDelaySeconds` high enough for startup
|
|
44
|
+
- Consider a **startupProbe** for slow-starting applications
|
|
45
|
+
|
|
46
|
+
## Security Context
|
|
47
|
+
|
|
48
|
+
ALL Pods MUST define a security context:
|
|
49
|
+
```yaml
|
|
50
|
+
securityContext:
|
|
51
|
+
runAsNonRoot: true
|
|
52
|
+
runAsUser: 1000
|
|
53
|
+
runAsGroup: 1000
|
|
54
|
+
fsGroup: 1000
|
|
55
|
+
allowPrivilegeEscalation: false
|
|
56
|
+
readOnlyRootFilesystem: true
|
|
57
|
+
capabilities:
|
|
58
|
+
drop:
|
|
59
|
+
- ALL
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Pod Security Standards
|
|
63
|
+
- Apply `restricted` Pod Security Standard where possible
|
|
64
|
+
- Never run containers as root
|
|
65
|
+
- Drop all Linux capabilities unless explicitly required
|
|
66
|
+
|
|
67
|
+
## Namespace
|
|
68
|
+
|
|
69
|
+
- Use explicit namespaces for all resources (never use `default`)
|
|
70
|
+
- Apply least-privilege RBAC per namespace
|
|
71
|
+
- Use `ResourceQuota` and `LimitRange` per namespace
|
|
72
|
+
|
|
73
|
+
```yaml
|
|
74
|
+
apiVersion: v1
|
|
75
|
+
kind: Namespace
|
|
76
|
+
metadata:
|
|
77
|
+
name: my-app
|
|
78
|
+
labels:
|
|
79
|
+
pod-security.kubernetes.io/enforce: restricted
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Secrets Management
|
|
83
|
+
|
|
84
|
+
- NEVER put secrets in YAML files committed to git
|
|
85
|
+
- Use Kubernetes Secrets or external secret managers:
|
|
86
|
+
- HashiCorp Vault
|
|
87
|
+
- AWS Secrets Manager / SSM Parameter Store
|
|
88
|
+
- Azure Key Vault
|
|
89
|
+
- Google Secret Manager
|
|
90
|
+
- Use `ExternalSecret` CRD or `sealed-secrets` for GitOps workflows
|
|
91
|
+
|
|
92
|
+
```yaml
|
|
93
|
+
apiVersion: v1
|
|
94
|
+
kind: Secret
|
|
95
|
+
metadata:
|
|
96
|
+
name: app-secrets
|
|
97
|
+
namespace: my-app
|
|
98
|
+
type: Opaque
|
|
99
|
+
stringData:
|
|
100
|
+
DATABASE_URL: "postgresql://user:pass@host:5432/db"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Deployment Pattern
|
|
104
|
+
|
|
105
|
+
```yaml
|
|
106
|
+
apiVersion: apps/v1
|
|
107
|
+
kind: Deployment
|
|
108
|
+
metadata:
|
|
109
|
+
name: my-app
|
|
110
|
+
namespace: my-app
|
|
111
|
+
labels:
|
|
112
|
+
app: my-app
|
|
113
|
+
spec:
|
|
114
|
+
replicas: 3
|
|
115
|
+
selector:
|
|
116
|
+
matchLabels:
|
|
117
|
+
app: my-app
|
|
118
|
+
strategy:
|
|
119
|
+
type: RollingUpdate
|
|
120
|
+
rollingUpdate:
|
|
121
|
+
maxSurge: 1
|
|
122
|
+
maxUnavailable: 0
|
|
123
|
+
template:
|
|
124
|
+
metadata:
|
|
125
|
+
labels:
|
|
126
|
+
app: my-app
|
|
127
|
+
spec:
|
|
128
|
+
securityContext:
|
|
129
|
+
runAsNonRoot: true
|
|
130
|
+
runAsUser: 1000
|
|
131
|
+
containers:
|
|
132
|
+
- name: my-app
|
|
133
|
+
image: my-registry/my-app:1.0.0
|
|
134
|
+
ports:
|
|
135
|
+
- containerPort: 3000
|
|
136
|
+
env:
|
|
137
|
+
- name: NODE_ENV
|
|
138
|
+
value: "production"
|
|
139
|
+
envFrom:
|
|
140
|
+
- secretRef:
|
|
141
|
+
name: app-secrets
|
|
142
|
+
resources:
|
|
143
|
+
requests:
|
|
144
|
+
memory: "128Mi"
|
|
145
|
+
cpu: "100m"
|
|
146
|
+
limits:
|
|
147
|
+
memory: "512Mi"
|
|
148
|
+
cpu: "500m"
|
|
149
|
+
readinessProbe:
|
|
150
|
+
httpGet:
|
|
151
|
+
path: /health
|
|
152
|
+
port: 3000
|
|
153
|
+
initialDelaySeconds: 5
|
|
154
|
+
periodSeconds: 10
|
|
155
|
+
livenessProbe:
|
|
156
|
+
httpGet:
|
|
157
|
+
path: /health
|
|
158
|
+
port: 3000
|
|
159
|
+
initialDelaySeconds: 15
|
|
160
|
+
periodSeconds: 20
|
|
161
|
+
securityContext:
|
|
162
|
+
allowPrivilegeEscalation: false
|
|
163
|
+
readOnlyRootFilesystem: true
|
|
164
|
+
capabilities:
|
|
165
|
+
drop: ["ALL"]
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Service Pattern
|
|
169
|
+
|
|
170
|
+
```yaml
|
|
171
|
+
apiVersion: v1
|
|
172
|
+
kind: Service
|
|
173
|
+
metadata:
|
|
174
|
+
name: my-app
|
|
175
|
+
namespace: my-app
|
|
176
|
+
spec:
|
|
177
|
+
selector:
|
|
178
|
+
app: my-app
|
|
179
|
+
ports:
|
|
180
|
+
- port: 80
|
|
181
|
+
targetPort: 3000
|
|
182
|
+
protocol: TCP
|
|
183
|
+
type: ClusterIP
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
## Labels and Annotations
|
|
187
|
+
|
|
188
|
+
Apply consistent labels to all resources:
|
|
189
|
+
```yaml
|
|
190
|
+
metadata:
|
|
191
|
+
labels:
|
|
192
|
+
app.kubernetes.io/name: my-app
|
|
193
|
+
app.kubernetes.io/version: "1.0.0"
|
|
194
|
+
app.kubernetes.io/component: backend
|
|
195
|
+
app.kubernetes.io/managed-by: helm
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Best Practices
|
|
199
|
+
|
|
200
|
+
- Use `RollingUpdate` strategy with `maxUnavailable: 0` for zero-downtime deploys
|
|
201
|
+
- Set `PodDisruptionBudget` for high-availability workloads
|
|
202
|
+
- Use `HorizontalPodAutoscaler` for auto-scaling
|
|
203
|
+
- Pin container image tags (never use `latest`)
|
|
204
|
+
- Use `NetworkPolicy` to restrict pod-to-pod communication
|
|
205
|
+
- Store configuration in `ConfigMap`, secrets in `Secret`
|
|
206
|
+
- Use `topologySpreadConstraints` for multi-zone distribution
|
|
207
|
+
|
|
208
|
+
<!-- KUBERNETES:END -->
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<!-- OPENTELEMETRY:START -->
|
|
2
|
+
# OpenTelemetry — Distributed Tracing
|
|
3
|
+
|
|
4
|
+
## Initialization
|
|
5
|
+
- Initialize OTel SDK BEFORE application code (use `--require` flag or top-level import)
|
|
6
|
+
- Configure exporter based on environment (OTLP, Jaeger, console for dev)
|
|
7
|
+
- Set `serviceName` from environment: `process.env.OTEL_SERVICE_NAME`
|
|
8
|
+
|
|
9
|
+
## Instrumentation
|
|
10
|
+
- Use auto-instrumentation packages for common libraries (HTTP, Express, pg)
|
|
11
|
+
- Create manual spans for business logic operations:
|
|
12
|
+
```typescript
|
|
13
|
+
const tracer = trace.getTracer('service-name');
|
|
14
|
+
const span = tracer.startSpan('operation.name');
|
|
15
|
+
try { ... } finally { span.end(); }
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Context Propagation
|
|
19
|
+
- Always propagate context across service boundaries using W3C Trace Context headers
|
|
20
|
+
- Use `context.with()` for async operations to preserve trace context
|
|
21
|
+
|
|
22
|
+
## Metrics
|
|
23
|
+
- Use `@opentelemetry/sdk-metrics` for custom metrics
|
|
24
|
+
- Follow naming conventions: `<namespace>.<metric_type>.<name>` (e.g., `http.server.request_count`)
|
|
25
|
+
<!-- OPENTELEMETRY:END -->
|