@rune-kit/rune 2.3.0 → 2.3.2

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.
Files changed (50) hide show
  1. package/README.md +395 -389
  2. package/compiler/__tests__/tier-override.test.js +158 -0
  3. package/compiler/adapters/antigravity.js +3 -8
  4. package/compiler/adapters/codex.js +3 -8
  5. package/compiler/adapters/cursor.js +3 -8
  6. package/compiler/adapters/generic.js +3 -8
  7. package/compiler/adapters/openclaw.js +4 -9
  8. package/compiler/adapters/opencode.js +3 -8
  9. package/compiler/adapters/windsurf.js +3 -8
  10. package/compiler/bin/rune.js +34 -1
  11. package/compiler/emitter.js +94 -5
  12. package/compiler/transforms/branding.js +10 -3
  13. package/docs/ARCHITECTURE.md +3 -3
  14. package/docs/VISION.md +3 -3
  15. package/docs/guides/index.html +14 -14
  16. package/docs/index.html +7 -7
  17. package/docs/skills/index.html +832 -832
  18. package/extensions/ai-ml/PACK.md +7 -0
  19. package/extensions/content/PACK.md +7 -0
  20. package/extensions/mobile/PACK.md +9 -9
  21. package/extensions/zalo/PACK.md +9 -0
  22. package/package.json +2 -2
  23. package/skills/audit/SKILL.md +526 -529
  24. package/skills/ba/SKILL.md +349 -351
  25. package/skills/completion-gate/SKILL.md +260 -263
  26. package/skills/context-engine/SKILL.md +0 -6
  27. package/skills/cook/SKILL.md +2 -11
  28. package/skills/db/SKILL.md +5 -1
  29. package/skills/db/references/scaling-reference.md +271 -0
  30. package/skills/debug/SKILL.md +392 -394
  31. package/skills/deploy/references/post-deploy-integration.md +192 -0
  32. package/skills/fix/SKILL.md +281 -282
  33. package/skills/onboard/SKILL.md +0 -4
  34. package/skills/plan/references/completeness-scoring.md +0 -1
  35. package/skills/plan/references/outcome-block.md +0 -1
  36. package/skills/plan/references/workflow-registry.md +0 -1
  37. package/skills/preflight/SKILL.md +360 -365
  38. package/skills/rescue/SKILL.md +1 -0
  39. package/skills/research/SKILL.md +149 -150
  40. package/skills/review/SKILL.md +489 -495
  41. package/skills/sentinel/SKILL.md +0 -11
  42. package/skills/sentinel/references/destructive-commands.md +0 -1
  43. package/skills/sentinel/references/skill-content-guard.md +0 -1
  44. package/skills/session-bridge/SKILL.md +0 -4
  45. package/skills/skill-forge/SKILL.md +5 -1
  46. package/skills/skill-forge/references/claude-skill-reference.md +182 -0
  47. package/skills/skill-router/{SKILL.md → skill.md} +446 -397
  48. package/skills/team/SKILL.md +1 -2
  49. package/skills/test/SKILL.md +585 -593
  50. package/skills/watchdog/references/webhook-health-checks.md +243 -0
@@ -3,7 +3,7 @@ name: db
3
3
  description: Database workflow specialist. Generates migration files with rollback scripts, detects breaking schema changes, and validates query parameterization.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.1.0"
6
+ version: "0.2.0"
7
7
  layer: L2
8
8
  model: sonnet
9
9
  group: development
@@ -35,6 +35,10 @@ Database workflow specialist. Handles the parts of database work that cause prod
35
35
  - `deploy` (L2): pre-deploy migration safety check
36
36
  - `audit` (L2): database health dimension
37
37
 
38
+ ## References
39
+
40
+ - `references/scaling-reference.md` — Index strategies, query optimization, N+1 prevention, connection pooling, read replicas, partitioning, sharding, denormalization. Load when scaling, performance, or indexing context detected.
41
+
38
42
  ## Executable Steps
39
43
 
40
44
  ### Step 1 — Discovery
@@ -0,0 +1,271 @@
1
+ # Database Scaling Reference
2
+
3
+ > Loaded by `db` skill when scaling, indexing, or performance optimization context is detected.
4
+ > Source patterns: production-proven PostgreSQL scaling strategies.
5
+
6
+ ---
7
+
8
+ ## Indexing Strategy
9
+
10
+ ### Index Type Selection
11
+
12
+ | Type | Use Case | Example |
13
+ |------|----------|---------|
14
+ | **B-tree** (default) | Equality, range, sorting | `WHERE id = 1`, `ORDER BY date` |
15
+ | **GIN** | Arrays, JSONB, full-text search | `WHERE tags @> ARRAY['a']` |
16
+ | **GiST** | Geometric, spatial, nearest-neighbor | PostGIS, `ORDER BY location <->` |
17
+ | **BRIN** | Large tables with natural ordering | Time-series > 100GB |
18
+
19
+ ### Compound Index Rules
20
+
21
+ Order columns: **equality → range → sort**
22
+
23
+ ```sql
24
+ -- Query: WHERE customer_id = X AND status IN (...) AND created_at > Y ORDER BY id
25
+ CREATE INDEX idx_orders ON orders(customer_id, status, created_at, id);
26
+ ```
27
+
28
+ ### Partial Indexes (index what you query)
29
+
30
+ ```sql
31
+ -- Only index active users (90% smaller, 90% faster writes)
32
+ CREATE INDEX idx_active_users ON users(email) WHERE status = 'active';
33
+
34
+ -- Only index pending orders
35
+ CREATE INDEX idx_pending_orders ON orders(customer_id) WHERE status = 'pending';
36
+ ```
37
+
38
+ ### Covering Indexes (avoid heap lookups)
39
+
40
+ ```sql
41
+ -- Query only needs total and date — include them in index
42
+ CREATE INDEX idx_orders_covering ON orders(customer_id)
43
+ INCLUDE (total, created_at);
44
+
45
+ -- Index-only scan — no heap access needed
46
+ SELECT total, created_at FROM orders WHERE customer_id = 123;
47
+ ```
48
+
49
+ ### Index Anti-Patterns
50
+
51
+ - Indexing every column (slows writes, wastes storage)
52
+ - Indexing low-cardinality columns alone (status with 3 values → useless)
53
+ - Missing indexes on foreign keys (kills JOIN performance)
54
+ - Unused indexes (check `pg_stat_user_indexes` for `idx_scan = 0`)
55
+
56
+ ---
57
+
58
+ ## Query Optimization
59
+
60
+ ### EXPLAIN ANALYZE — Always Profile
61
+
62
+ ```sql
63
+ EXPLAIN (ANALYZE, BUFFERS, TIMING ON)
64
+ SELECT * FROM orders WHERE customer_id = 123 AND created_at > NOW() - INTERVAL '30d';
65
+ ```
66
+
67
+ **Red flags in output:**
68
+ - `Seq Scan` on large table → missing index
69
+ - `Filter` removes most rows → index should be more selective
70
+ - `Sort` with high cost → add index that matches ORDER BY
71
+ - `Nested Loop` with large outer table → consider hash/merge join
72
+
73
+ ### pg_stat_statements — Find Problem Queries
74
+
75
+ ```sql
76
+ -- Top 10 slowest queries by total time
77
+ SELECT query, calls, total_exec_time / 1000 AS total_sec,
78
+ mean_exec_time AS avg_ms,
79
+ 100.0 * shared_blks_hit / NULLIF(shared_blks_hit + shared_blks_read, 0) AS cache_pct
80
+ FROM pg_stat_statements
81
+ ORDER BY total_exec_time DESC LIMIT 10;
82
+
83
+ -- N+1 detector: queries called many times with low individual cost
84
+ SELECT query, calls, mean_exec_time AS avg_ms
85
+ FROM pg_stat_statements
86
+ WHERE calls > 1000 AND mean_exec_time < 5
87
+ ORDER BY calls DESC LIMIT 10;
88
+ ```
89
+
90
+ ---
91
+
92
+ ## N+1 Query Prevention
93
+
94
+ ### Prisma
95
+
96
+ ```typescript
97
+ // BAD: 1 + N queries
98
+ const users = await prisma.user.findMany();
99
+ for (const u of users) {
100
+ u.posts = await prisma.post.findMany({ where: { authorId: u.id } });
101
+ }
102
+
103
+ // GOOD: 2 queries (parallel fetch)
104
+ const users = await prisma.user.findMany({ include: { posts: true } });
105
+
106
+ // GOOD: Single query (database JOIN)
107
+ const users = await prisma.user.findMany({
108
+ relationLoadStrategy: 'join',
109
+ include: { posts: { select: { id: true, title: true } } }
110
+ });
111
+ ```
112
+
113
+ ### Drizzle (no N+1 by design)
114
+
115
+ ```typescript
116
+ const results = await db.select().from(users)
117
+ .leftJoin(posts, eq(users.id, posts.userId));
118
+ ```
119
+
120
+ ### Detection
121
+
122
+ Enable query logging — look for **query count = 1 + N** where N = row count.
123
+
124
+ ```typescript
125
+ // Prisma query logging
126
+ const prisma = new PrismaClient({ log: [{ emit: 'event', level: 'query' }] });
127
+ prisma.$on('query', (e) => {
128
+ if (e.duration > 100) console.warn(`SLOW: ${e.duration}ms — ${e.query}`);
129
+ });
130
+ ```
131
+
132
+ ---
133
+
134
+ ## Connection Pooling
135
+
136
+ ### Sizing Formula
137
+
138
+ ```
139
+ pool_size = (CPU cores × 2) + effective_spindle_count
140
+
141
+ 4-core → 9 connections
142
+ 8-core → 17 connections
143
+ 16-core → 33 connections
144
+ ```
145
+
146
+ ### PgBouncer Configuration
147
+
148
+ ```ini
149
+ [pgbouncer]
150
+ pool_mode = transaction # Release after each transaction
151
+ default_pool_size = 25 # Per database/user pair
152
+ min_pool_size = 10 # Keep warm
153
+ reserve_pool_size = 5 # Overflow buffer
154
+ max_client_connections = 1000 # Total client limit
155
+ server_idle_timeout = 600 # Close idle server connections (10min)
156
+ query_wait_timeout = 120 # Max wait for available connection
157
+ ```
158
+
159
+ **Warning signs:** Pool utilization > 80%, rising wait times, connection timeouts.
160
+
161
+ ---
162
+
163
+ ## Read Replicas
164
+
165
+ ### When to Add
166
+
167
+ - Read:write ratio exceeds **10:1**
168
+ - Primary CPU consistently > 70% from read queries
169
+ - Analytics queries competing with transactional reads
170
+
171
+ ### Routing Pattern
172
+
173
+ ```typescript
174
+ const primaryPool = new Pool({ host: 'primary.db.com' });
175
+ const replicaPool = new Pool({ host: 'replica.db.com' });
176
+
177
+ async function query(sql: string, params: unknown[], opts?: { write?: boolean }) {
178
+ const pool = opts?.write ? primaryPool : replicaPool;
179
+ return pool.query(sql, params);
180
+ }
181
+ ```
182
+
183
+ ### Replication Lag
184
+
185
+ - Typical: 5-50ms for well-tuned async replication
186
+ - **Read-your-writes consistency**: After a write, read from primary for that user's session
187
+ - **Analytics queries**: Always safe on replicas (stale data acceptable)
188
+
189
+ ---
190
+
191
+ ## Partitioning
192
+
193
+ ### When to Partition
194
+
195
+ - Table exceeds **100GB** or **100M+ rows**
196
+ - Queries always filter on a specific column (date, tenant)
197
+ - Need fast deletion of old data (`DROP` partition vs `DELETE`)
198
+
199
+ ### Range Partitioning (time-series)
200
+
201
+ ```sql
202
+ CREATE TABLE events (
203
+ id BIGSERIAL, created_at TIMESTAMPTZ NOT NULL, data JSONB
204
+ ) PARTITION BY RANGE (created_at);
205
+
206
+ CREATE TABLE events_2025_01 PARTITION OF events
207
+ FOR VALUES FROM ('2025-01-01') TO ('2025-02-01');
208
+
209
+ -- Delete old data instantly
210
+ DROP TABLE events_2024_01; -- 0.01s vs DELETE minutes
211
+ ```
212
+
213
+ ### Hash Partitioning (even distribution)
214
+
215
+ ```sql
216
+ CREATE TABLE orders (id BIGSERIAL, customer_id INT, data JSONB)
217
+ PARTITION BY HASH (customer_id);
218
+
219
+ CREATE TABLE orders_0 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 0);
220
+ CREATE TABLE orders_1 PARTITION OF orders FOR VALUES WITH (MODULUS 4, REMAINDER 1);
221
+ ```
222
+
223
+ **Rule:** Keep partition count under 500 — query planning overhead grows with partition count.
224
+
225
+ ---
226
+
227
+ ## Sharding Decision Matrix
228
+
229
+ ### When to Shard (Last Resort)
230
+
231
+ | Strategy | Pros | Cons |
232
+ |----------|------|------|
233
+ | **Hash-based** | Even distribution | No range queries on shard key |
234
+ | **Range-based** | Range queries work | Hot shards if distribution skewed |
235
+ | **Tenant-based** | Strong isolation | Uneven if tenants vary in size |
236
+
237
+ ### Before Sharding, Try These First
238
+
239
+ 1. Add proper indexes
240
+ 2. Fix N+1 queries
241
+ 3. Add read replicas
242
+ 4. Add caching layer
243
+ 5. Partition large tables
244
+ 6. Vertical scaling (bigger instance)
245
+ 7. Archive old data
246
+ 8. Optimize queries with EXPLAIN ANALYZE
247
+
248
+ ---
249
+
250
+ ## Denormalization Decision Matrix
251
+
252
+ | Scenario | Keep Normalized | Denormalize |
253
+ |----------|----------------|-------------|
254
+ | High write volume | Yes | No |
255
+ | High read volume, slow joins | No | Yes |
256
+ | Data consistency critical | Yes | No |
257
+ | Analytics / reporting | No | Yes (materialized views) |
258
+
259
+ ### Materialized Views
260
+
261
+ ```sql
262
+ CREATE MATERIALIZED VIEW order_stats AS
263
+ SELECT customer_id, COUNT(*) AS order_count, SUM(total) AS total_spent
264
+ FROM orders GROUP BY customer_id;
265
+
266
+ -- Refresh periodically (CONCURRENTLY allows reads during refresh)
267
+ REFRESH MATERIALIZED VIEW CONCURRENTLY order_stats;
268
+ CREATE UNIQUE INDEX ON order_stats(customer_id);
269
+ ```
270
+
271
+ **Rule:** Start normalized. Denormalize specific queries only when EXPLAIN shows expensive joins that caching can't solve.