@rune-kit/rune 2.2.2 → 2.2.3

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 (37) hide show
  1. package/compiler/__tests__/adapters.test.js +109 -0
  2. package/compiler/__tests__/openclaw-adapter.test.js +149 -140
  3. package/compiler/__tests__/pack-split.test.js +145 -145
  4. package/compiler/__tests__/parser.test.js +3 -3
  5. package/compiler/__tests__/pipeline.test.js +110 -0
  6. package/compiler/__tests__/skill-validation.test.js +148 -0
  7. package/compiler/__tests__/transformer.test.js +70 -0
  8. package/compiler/__tests__/transforms.test.js +92 -0
  9. package/compiler/adapters/antigravity.js +5 -6
  10. package/compiler/adapters/claude.js +1 -1
  11. package/compiler/adapters/codex.js +69 -77
  12. package/compiler/adapters/cursor.js +5 -6
  13. package/compiler/adapters/generic.js +5 -6
  14. package/compiler/adapters/index.js +3 -3
  15. package/compiler/adapters/openclaw.js +146 -150
  16. package/compiler/adapters/opencode.js +78 -86
  17. package/compiler/adapters/windsurf.js +5 -6
  18. package/compiler/bin/rune.js +32 -23
  19. package/compiler/doctor.js +19 -7
  20. package/compiler/emitter.js +11 -18
  21. package/compiler/parser.js +5 -5
  22. package/compiler/transformer.js +3 -5
  23. package/compiler/transforms/branding.js +5 -4
  24. package/compiler/transforms/compliance.js +40 -40
  25. package/compiler/transforms/frontmatter.js +1 -1
  26. package/compiler/transforms/hooks.js +12 -14
  27. package/compiler/transforms/subagents.js +1 -3
  28. package/compiler/transforms/tool-names.js +1 -1
  29. package/docs/guides/index.html +48 -7
  30. package/docs/index.html +67 -2
  31. package/docs/style.css +18 -1
  32. package/extensions/security/PACK.md +4 -3
  33. package/extensions/security/skills/defense-in-depth.md +103 -0
  34. package/package.json +8 -1
  35. package/skills/debug/SKILL.md +16 -1
  36. package/skills/skill-forge/SKILL.md +57 -1
  37. package/skills/test/SKILL.md +35 -2
@@ -8,12 +8,14 @@
8
8
  const HOOK_CONSTRAINTS = [
9
9
  {
10
10
  id: 'secrets-scan',
11
- instruction: 'MUST NOT: Never run commands containing hardcoded secrets, API keys, or tokens. Scan all shell commands for secret patterns before execution.',
11
+ instruction:
12
+ 'MUST NOT: Never run commands containing hardcoded secrets, API keys, or tokens. Scan all shell commands for secret patterns before execution.',
12
13
  relevantTools: ['Bash'],
13
14
  },
14
15
  {
15
16
  id: 'auto-format',
16
- instruction: 'MUST: After editing JS/TS files, ensure code follows project formatting conventions (Prettier/ESLint).',
17
+ instruction:
18
+ 'MUST: After editing JS/TS files, ensure code follows project formatting conventions (Prettier/ESLint).',
17
19
  relevantTools: ['Edit', 'Write'],
18
20
  },
19
21
  {
@@ -23,7 +25,8 @@ const HOOK_CONSTRAINTS = [
23
25
  },
24
26
  {
25
27
  id: 'context-watch',
26
- instruction: 'SHOULD: Monitor your context usage. If working on a long task, summarize progress before context fills up.',
28
+ instruction:
29
+ 'SHOULD: Monitor your context usage. If working on a long task, summarize progress before context fills up.',
27
30
  relevantTools: [],
28
31
  },
29
32
  {
@@ -33,7 +36,8 @@ const HOOK_CONSTRAINTS = [
33
36
  },
34
37
  {
35
38
  id: 'post-session',
36
- instruction: 'SHOULD: Before ending, save architectural decisions and progress to .rune/ directory for future sessions.',
39
+ instruction:
40
+ 'SHOULD: Before ending, save architectural decisions and progress to .rune/ directory for future sessions.',
37
41
  relevantTools: [],
38
42
  },
39
43
  ];
@@ -49,20 +53,14 @@ export function generateHookConstraints(parsedSkill, adapter) {
49
53
  if (adapter.name === 'claude') return '';
50
54
 
51
55
  // Filter to relevant constraints based on tool usage in this skill
52
- const skillToolNames = parsedSkill.toolRefs.map(r => r.toolName);
53
- const relevant = HOOK_CONSTRAINTS.filter(h =>
54
- h.relevantTools.length === 0 || h.relevantTools.some(t => skillToolNames.includes(t))
56
+ const skillToolNames = parsedSkill.toolRefs.map((r) => r.toolName);
57
+ const relevant = HOOK_CONSTRAINTS.filter(
58
+ (h) => h.relevantTools.length === 0 || h.relevantTools.some((t) => skillToolNames.includes(t)),
55
59
  );
56
60
 
57
61
  if (relevant.length === 0) return '';
58
62
 
59
- const lines = [
60
- '',
61
- '## Platform Constraints',
62
- '',
63
- ...relevant.map(h => `- ${h.instruction}`),
64
- '',
65
- ];
63
+ const lines = ['', '## Platform Constraints', '', ...relevant.map((h) => `- ${h.instruction}`), ''];
66
64
 
67
65
  return lines.join('\n');
68
66
  }
@@ -30,7 +30,5 @@ export function transformSubagents(body, adapter) {
30
30
  result = result.replace(pattern, replace);
31
31
  }
32
32
 
33
- return adapter.transformSubagentInstruction
34
- ? adapter.transformSubagentInstruction(result)
35
- : result;
33
+ return adapter.transformSubagentInstruction ? adapter.transformSubagentInstruction(result) : result;
36
34
  }
@@ -41,7 +41,7 @@ export function transformToolNames(body, adapter) {
41
41
  let result = body.replace(TOOL_INSTRUCTION_TO_PATTERN, (match, toolName) => {
42
42
  const mapped = adapter.transformToolName(toolName);
43
43
  if (mapped === toolName) return match;
44
- return mapped.charAt(0).toUpperCase() + mapped.slice(1) + ' to ';
44
+ return `${mapped.charAt(0).toUpperCase() + mapped.slice(1)} to `;
45
45
  });
46
46
 
47
47
  // Second: "Use `Tool`:" or "Use `Tool`." patterns
@@ -561,22 +561,26 @@
561
561
  <button class="tab-btn" data-tab="install-cursor">Cursor</button>
562
562
  <button class="tab-btn" data-tab="install-windsurf">Windsurf</button>
563
563
  <button class="tab-btn" data-tab="install-antigravity">Antigravity</button>
564
+ <button class="tab-btn" data-tab="install-openclaw">OpenClaw</button>
564
565
  </div>
565
566
 
566
567
  <div class="tab-panel active" id="install-claude">
567
568
  <p>Claude Code uses Rune as a <strong>native plugin</strong> — no compilation needed.</p>
568
569
  <div class="code-wrapper">
569
- <div class="code-block"><span class="comment"># Install the plugin</span>
570
- <span class="cmd">claude plugin install rune-kit/rune</span>
570
+ <div class="code-block"><span class="comment"># Step 1: Add marketplace (one-time)</span>
571
+ <span class="cmd">claude plugin marketplace add rune-kit/rune</span>
572
+
573
+ <span class="comment"># Step 2: Install the plugin</span>
574
+ <span class="cmd">claude plugin install rune</span>
571
575
 
572
576
  <span class="comment"># Verify it's loaded</span>
573
577
  <span class="cmd">claude</span>
574
578
  <span class="output"> 58 skills loaded from rune</span></div>
575
- <button class="copy-btn" data-copy="claude plugin install rune-kit/rune">Copy</button>
579
+ <button class="copy-btn" data-copy="claude plugin marketplace add rune-kit/rune && claude plugin install rune">Copy</button>
576
580
  </div>
577
581
  <div class="callout callout-tip">
578
- <strong>Tip:</strong> Claude Code loads SKILL.md files directly from the plugin source.
579
- No compilation step, no configuration needed. Just install and go.
582
+ <strong>Tip:</strong> The marketplace only needs to be added once. After that,
583
+ just <code>claude plugin install rune</code> or <code>claude plugin update rune</code>.
580
584
  </div>
581
585
  </div>
582
586
 
@@ -618,6 +622,21 @@
618
622
  or via your Google Cloud workspace.
619
623
  </div>
620
624
  </div>
625
+
626
+ <div class="tab-panel" id="install-openclaw">
627
+ <p>OpenClaw uses Rune as a unified mesh package from <strong>ClawHub</strong>.</p>
628
+ <div class="code-wrapper">
629
+ <div class="code-block"><span class="cmd">clawhub install rune-kit</span>
630
+
631
+ <span class="comment"># All 58 skills installed as one mesh package</span>
632
+ <span class="comment"># Works with any OpenClaw-compatible agent</span></div>
633
+ <button class="copy-btn" data-copy="clawhub install rune-kit">Copy</button>
634
+ </div>
635
+ <div class="callout callout-info">
636
+ <strong>Note:</strong> Rune is published as a single unified package on ClawHub.
637
+ Individual skills are NOT published separately — the mesh requires all skills together.
638
+ </div>
639
+ </div>
621
640
  </div>
622
641
 
623
642
  <!-- FIRST RUN -->
@@ -933,8 +952,11 @@
933
952
  </p>
934
953
 
935
954
  <div class="code-wrapper">
936
- <div class="code-block"><span class="comment"># Install</span>
937
- <span class="cmd">claude plugin install rune-kit/rune</span>
955
+ <div class="code-block"><span class="comment"># Step 1: Add marketplace (one-time)</span>
956
+ <span class="cmd">claude plugin marketplace add rune-kit/rune</span>
957
+
958
+ <span class="comment"># Step 2: Install</span>
959
+ <span class="cmd">claude plugin install rune</span>
938
960
 
939
961
  <span class="comment"># Use any skill directly</span>
940
962
  <span class="cmd">/rune cook "add user authentication"</span>
@@ -1038,6 +1060,25 @@
1038
1060
  <code>.agents/skills/</code> — so Claude-compatible skill formats work too.
1039
1061
  </div>
1040
1062
 
1063
+ <h2 id="ide-openclaw">OpenClaw (ClawHub)</h2>
1064
+
1065
+ <p>
1066
+ OpenClaw agents can install Rune from <strong>ClawHub</strong> — the skill registry for the
1067
+ OpenClaw ecosystem. Rune is published as a single unified package (not individual skills).
1068
+ </p>
1069
+
1070
+ <div class="code-wrapper">
1071
+ <div class="code-block"><span class="cmd">clawhub install rune-kit</span>
1072
+
1073
+ <span class="comment"># All 58 skills + 14 extension packs as one mesh package</span>
1074
+ <span class="comment"># Slug: rune-kit on clawhub.ai</span></div>
1075
+ </div>
1076
+
1077
+ <div class="callout callout-warn">
1078
+ <strong>Important:</strong> Rune skills are NOT published individually on ClawHub.
1079
+ The mesh requires all 200+ connections to function — installing skills separately would break routing.
1080
+ </div>
1081
+
1041
1082
  <div class="callout callout-info">
1042
1083
  <strong>All platforms get the same 58 skills.</strong> The compiler handles format differences.
1043
1084
  Cross-references, tool names, and model hints are adapted per platform.
package/docs/index.html CHANGED
@@ -61,7 +61,7 @@
61
61
  <canvas id="mesh-canvas"></canvas>
62
62
  </div>
63
63
  <div class="hero-content">
64
- <p class="hero-badge">v2.2.1 &mdash; 58 skills &bull; 8 platforms &bull; MIT</p>
64
+ <p class="hero-badge">v2.2.2 &mdash; 58 skills &bull; 8 platforms &bull; MIT</p>
65
65
  <h1>Less skills.<br><span class="accent">Deeper connections.</span></h1>
66
66
  <p class="hero-sub">A mesh ecosystem for AI coding assistants. Skills call each other bidirectionally, forming resilient workflows that adapt when things go wrong.</p>
67
67
  <div class="hero-actions">
@@ -244,7 +244,11 @@ D &harr; E &harr; F
244
244
  <div class="install-card">
245
245
  <h3>Claude Code</h3>
246
246
  <p class="install-badge">Native Plugin</p>
247
- <pre class="code-block"><code>/plugin install rune@rune-kit</code></pre>
247
+ <pre class="code-block"><code># Add marketplace (one-time)
248
+ claude plugin marketplace add rune-kit/rune
249
+
250
+ # Install plugin
251
+ claude plugin install rune</code></pre>
248
252
  <p>Full mesh: subagents, hooks, adaptive routing, analytics.</p>
249
253
  </div>
250
254
  <div class="install-card">
@@ -253,6 +257,67 @@ D &harr; E &harr; F
253
257
  <pre class="code-block"><code>npx @rune-kit/rune init</code></pre>
254
258
  <p>Auto-detects platform. Compiles all 58 skills to native rule format.</p>
255
259
  </div>
260
+ <div class="install-card">
261
+ <h3>OpenClaw</h3>
262
+ <p class="install-badge">ClawHub Registry</p>
263
+ <pre class="code-block"><code>clawhub install rune-kit</code></pre>
264
+ <p>58 skills as unified mesh package. Works with any OpenClaw agent.</p>
265
+ </div>
266
+ </div>
267
+ </div>
268
+ </section>
269
+
270
+ <!-- GUIDES DIRECTORY -->
271
+ <section class="section section-dark" id="learn">
272
+ <div class="container">
273
+ <h2>Learn Rune</h2>
274
+ <p class="section-sub">From first install to advanced mesh orchestration &mdash; everything in one place.</p>
275
+ <div class="guide-grid">
276
+ <a href="guides/#install" class="guide-link">
277
+ <span class="guide-icon">&#9889;</span>
278
+ <div>
279
+ <strong>Quick Start</strong>
280
+ <span>Install + first run in 2 minutes</span>
281
+ </div>
282
+ </a>
283
+ <a href="guides/#mesh-architecture" class="guide-link">
284
+ <span class="guide-icon">&#9670;</span>
285
+ <div>
286
+ <strong>Mesh Architecture</strong>
287
+ <span>How 200+ connections work</span>
288
+ </div>
289
+ </a>
290
+ <a href="guides/#wf-cook" class="guide-link">
291
+ <span class="guide-icon">&#9881;</span>
292
+ <div>
293
+ <strong>Workflows</strong>
294
+ <span>cook, rescue, team, debug</span>
295
+ </div>
296
+ </a>
297
+ <a href="guides/#ide-claude" class="guide-link">
298
+ <span class="guide-icon">&#128187;</span>
299
+ <div>
300
+ <strong>Platform Guides</strong>
301
+ <span>Claude, Cursor, Windsurf, Codex, OpenClaw</span>
302
+ </div>
303
+ </a>
304
+ <a href="guides/#ext-using" class="guide-link">
305
+ <span class="guide-icon">&#128230;</span>
306
+ <div>
307
+ <strong>Extension Packs</strong>
308
+ <span>14 domain packs + create your own</span>
309
+ </div>
310
+ </a>
311
+ <a href="guides/#faq" class="guide-link">
312
+ <span class="guide-icon">&#10067;</span>
313
+ <div>
314
+ <strong>FAQ &amp; Troubleshooting</strong>
315
+ <span>Common issues + answers</span>
316
+ </div>
317
+ </a>
318
+ </div>
319
+ <div style="text-align:center;margin-top:24px">
320
+ <a href="guides/" class="btn btn-ghost">View Full Guide &rarr;</a>
256
321
  </div>
257
322
  </div>
258
323
  </section>
package/docs/style.css CHANGED
@@ -245,7 +245,7 @@ a:hover { opacity: 0.85; }
245
245
  .feature-card p { font-size: 14px; color: var(--text-secondary); line-height: 1.6; }
246
246
 
247
247
  /* ─── INSTALL ─── */
248
- .install-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; max-width: 800px; margin: 0 auto; }
248
+ .install-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; max-width: 960px; margin: 0 auto; }
249
249
  .install-card {
250
250
  background: var(--bg-card); border: 1px solid var(--border);
251
251
  border-radius: var(--radius-lg); padding: 32px; text-align: center;
@@ -264,6 +264,23 @@ a:hover { opacity: 0.85; }
264
264
  }
265
265
  .install-card p:last-child { font-size: 14px; color: var(--text-secondary); }
266
266
 
267
+ /* ─── GUIDE DIRECTORY ─── */
268
+ .guide-grid {
269
+ display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
270
+ gap: 12px; max-width: 960px; margin: 0 auto;
271
+ }
272
+ .guide-link {
273
+ display: flex; align-items: center; gap: 16px;
274
+ padding: 16px 20px; background: var(--bg-card);
275
+ border: 1px solid var(--border); border-radius: var(--radius-md);
276
+ color: var(--text-primary);
277
+ transition: border-color var(--transition), transform var(--transition);
278
+ }
279
+ .guide-link:hover { border-color: var(--accent); transform: translateY(-2px); opacity: 1; }
280
+ .guide-icon { font-size: 24px; flex-shrink: 0; }
281
+ .guide-link strong { display: block; font-size: 15px; margin-bottom: 2px; }
282
+ .guide-link span { font-size: 13px; color: var(--text-secondary); }
283
+
267
284
  /* ─── PRICING ─── */
268
285
 
269
286
  /* Persona cards — "who needs what" */
@@ -3,7 +3,7 @@ name: "@rune/security"
3
3
  description: Deep security analysis — OWASP audit, penetration testing patterns, secret management, compliance checking, supply chain security, and API hardening.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.2.0"
6
+ version: "0.3.0"
7
7
  layer: L4
8
8
  price: "$15"
9
9
  target: Security engineers
@@ -20,12 +20,12 @@ tools:
20
20
 
21
21
  ## Purpose
22
22
 
23
- @rune/security delivers manual-grade security analysis for teams that need more than an automated gate. Where `sentinel` (L2) runs fast checks on every commit, this pack runs thorough, on-demand audits: threat modeling entire auth flows, mapping real attack surfaces, designing vault strategies, auditing supply chain integrity, hardening API surfaces, and producing compliance audit trails. All six skills share the same threat mindset — assume breach, prove safety, document evidence.
23
+ @rune/security delivers manual-grade security analysis for teams that need more than an automated gate. Where `sentinel` (L2) runs fast checks on every commit, this pack runs thorough, on-demand audits: threat modeling entire auth flows, mapping real attack surfaces, designing vault strategies, auditing supply chain integrity, hardening API surfaces, enforcing multi-layer validation, and producing compliance audit trails. All seven skills share the same threat mindset — assume breach, prove safety, document evidence.
24
24
 
25
25
  ## Triggers
26
26
 
27
27
  - `/rune security` — manual invocation, full pack audit
28
- - `/rune owasp-audit` | `/rune pentest-patterns` | `/rune secret-mgmt` | `/rune compliance` | `/rune supply-chain` | `/rune api-security` — single skill invocation
28
+ - `/rune owasp-audit` | `/rune pentest-patterns` | `/rune secret-mgmt` | `/rune compliance` | `/rune supply-chain` | `/rune api-security` | `/rune defense-in-depth` — single skill invocation
29
29
  - Called by `cook` (L1) when auth, crypto, payment, or PII-handling code is detected
30
30
  - Called by `review` (L2) when security-critical patterns are flagged during code review
31
31
  - Called by `deploy` (L2) before production releases when security scope is active
@@ -40,6 +40,7 @@ tools:
40
40
  | [compliance](skills/compliance.md) | opus | SOC 2, GDPR, HIPAA, PCI-DSS v4.0 gap analysis, automated evidence collection, and audit-ready evidence packages. |
41
41
  | [supply-chain](skills/supply-chain.md) | sonnet | Dependency confusion attacks, typosquatting, lockfile injection, manifest confusion, and SLSA provenance verification. |
42
42
  | [api-security](skills/api-security.md) | sonnet | Rate limiting, input sanitization, CORS, CSP generation, and security headers middleware for Express, Fastify, and Next.js. |
43
+ | [defense-in-depth](skills/defense-in-depth.md) | sonnet | Multi-layer validation strategy — add validation at every layer data passes through (entry, business logic, environment, instrumentation). |
43
44
 
44
45
  ## Connections
45
46
 
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: "defense-in-depth"
3
+ pack: "@rune/security"
4
+ description: "Multi-layer validation strategy — add validation at EVERY layer data passes through, not just the entry point. Prevents single-point-of-failure in input handling."
5
+ model: sonnet
6
+ tools: [Read, Edit, Write, Grep, Glob, Bash]
7
+ ---
8
+
9
+ # defense-in-depth
10
+
11
+ Multi-layer validation strategy. When a bug is caused by invalid data flowing through the system, the fix must add validation at EVERY layer — not just where the error appeared. Different code paths bypass single validation points. All four layers are necessary; during testing, each catches bugs the others miss.
12
+
13
+ #### When to Use
14
+
15
+ - After `debug` finds a root cause involving invalid data propagation
16
+ - When `owasp-audit` identifies input validation gaps across multiple boundaries
17
+ - During new feature implementation where data crosses 3+ layers (API → service → DB)
18
+ - When a fix at one layer didn't prevent the same class of bug from recurring at another layer
19
+
20
+ #### The 4-Layer Model
21
+
22
+ | Layer | Purpose | What to Validate | Example |
23
+ |-------|---------|------------------|---------|
24
+ | **L1: Entry Point** | Reject invalid input at system boundary | Schema, type, format, size | Zod schema at API route, CLI arg parser |
25
+ | **L2: Business Logic** | Ensure data makes sense for the operation | Semantic validity, permissions, state | "User owns this resource", "balance >= withdrawal" |
26
+ | **L3: Environment Guards** | Prevent dangerous operations in wrong context | Path containment, env checks, capability limits | Refuse `git init` outside tmpdir in tests, block prod writes in dev |
27
+ | **L4: Debug Instrumentation** | Capture context for forensics when layers 1-3 fail | Stack traces, data snapshots at boundaries | `console.error` with full context before dangerous operations |
28
+
29
+ #### Workflow
30
+
31
+ **Step 1 — Map Data Flow**
32
+ Trace the path of the problematic data from entry point to crash site. Identify every function boundary it crosses. Each boundary is a potential validation layer.
33
+
34
+ **Step 2 — Audit Existing Validation**
35
+ For each boundary, check: does validation exist? Is it sufficient? Common gaps:
36
+ - Entry point validates type but not semantic meaning (e.g., "is string" but not "is valid email")
37
+ - Business logic assumes entry point already validated (no redundancy)
38
+ - Environment guards absent entirely (test code can hit production paths)
39
+ - No instrumentation to diagnose future failures
40
+
41
+ **Step 3 — Add Missing Layers**
42
+ For each gap, add validation appropriate to that layer:
43
+
44
+ ```typescript
45
+ // L1: Entry Point — schema validation
46
+ const CreateOrderSchema = z.object({
47
+ userId: z.string().uuid(),
48
+ amount: z.number().positive().max(100000),
49
+ currency: z.enum(['USD', 'EUR', 'VND']),
50
+ })
51
+
52
+ // L2: Business Logic — semantic validation
53
+ async function createOrder(data: CreateOrderInput) {
54
+ const user = await db.users.findById(data.userId)
55
+ if (!user) throw new NotFoundError('User not found')
56
+ if (user.balance < data.amount) throw new InsufficientFundsError()
57
+ // proceed...
58
+ }
59
+
60
+ // L3: Environment Guard — context protection
61
+ function writeToPath(targetDir: string, filename: string) {
62
+ const resolved = path.resolve(targetDir, filename)
63
+ if (!resolved.startsWith(path.resolve(targetDir))) {
64
+ throw new SecurityError('Path traversal attempt blocked')
65
+ }
66
+ if (process.env.NODE_ENV === 'test' && !resolved.startsWith('/tmp')) {
67
+ throw new SecurityError('Test environment: writes restricted to /tmp')
68
+ }
69
+ }
70
+
71
+ // L4: Debug Instrumentation — forensic context
72
+ function dangerousOperation(input: unknown) {
73
+ console.error('[DEFENSE] dangerousOperation called with:', {
74
+ input,
75
+ stack: new Error().stack,
76
+ env: process.env.NODE_ENV,
77
+ timestamp: new Date().toISOString(),
78
+ })
79
+ // proceed with operation...
80
+ }
81
+ ```
82
+
83
+ **Step 4 — Verify All Layers**
84
+ Write tests that bypass each individual layer and confirm the next layer catches it:
85
+ - Test L2 with valid-schema but semantically invalid data (passes L1, caught by L2)
86
+ - Test L3 with valid business data but wrong environment (passes L1+L2, caught by L3)
87
+ - If any single-layer bypass succeeds end-to-end → the defense is incomplete
88
+
89
+ #### Sharp Edges
90
+
91
+ | Failure Mode | Severity | Mitigation |
92
+ |---|---|---|
93
+ | Fixing only at crash site, not at data origin | CRITICAL | Backward trace: fix at source AND add guards at each intermediate layer |
94
+ | L1 validation gives false sense of security | HIGH | L1 validates format only — L2 must validate meaning and permissions |
95
+ | Environment guards missing in test context | HIGH | L3: add `NODE_ENV` checks to prevent test pollution and dangerous operations |
96
+ | No forensic trail when all layers are bypassed | MEDIUM | L4: always log context before irreversible operations |
97
+
98
+ #### Connection to Other Skills
99
+
100
+ - Called by `debug` (L2): after root cause found, recommend defense-in-depth fix via `rune:fix`
101
+ - Called by `owasp-audit` (L4): when audit finds validation only at entry point
102
+ - Complements `sentinel` (L2): sentinel gates commits, defense-in-depth designs the validation architecture
103
+ - Informs `api-security` (L4): API hardening is L1 of this model; defense-in-depth extends to all layers
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rune-kit/rune",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "description": "58-skill mesh for AI coding assistants — 5-layer architecture, 200+ connections, 8 platforms (Claude Code, Cursor, Windsurf, Antigravity, Codex, OpenCode, OpenClaw, Generic)",
5
5
  "type": "module",
6
6
  "bin": {
@@ -10,6 +10,10 @@
10
10
  "build": "node compiler/bin/rune.js build",
11
11
  "doctor": "node compiler/bin/rune.js doctor && node scripts/version-sync-check.js",
12
12
  "test": "node --test compiler/__tests__/*.test.js",
13
+ "lint": "biome check .",
14
+ "lint:fix": "biome check --fix .",
15
+ "format": "biome format --write .",
16
+ "ci": "biome check . && node --test compiler/__tests__/*.test.js && node compiler/bin/rune.js doctor",
13
17
  "version-check": "node scripts/version-sync-check.js",
14
18
  "prepublishOnly": "node scripts/version-sync-check.js"
15
19
  },
@@ -51,5 +55,8 @@
51
55
  "homepage": "https://github.com/rune-kit/rune",
52
56
  "bugs": {
53
57
  "url": "https://github.com/rune-kit/rune/issues"
58
+ },
59
+ "devDependencies": {
60
+ "@biomejs/biome": "^2.4.7"
54
61
  }
55
62
  }
@@ -3,7 +3,7 @@ name: debug
3
3
  description: Root cause analysis for bugs and unexpected behavior. Traces errors through code, uses structured reasoning, and hands off to fix when cause is found. Core of the debug↔fix mesh.
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.4.0"
6
+ version: "0.5.0"
7
7
  layer: L2
8
8
  model: sonnet
9
9
  group: development
@@ -89,6 +89,21 @@ When the error appears deep in execution (wrong directory, wrong path, wrong val
89
89
 
90
90
  Rule: NEVER fix where the error appears. Trace back to where invalid data originated.
91
91
 
92
+ #### Instrumentation Tip: Use console.error, Not Loggers
93
+ When adding diagnostic instrumentation, use `console.error()` (stderr) — NOT application loggers. Loggers are configured to suppress output based on log level or environment (e.g., `LOG_LEVEL=warn` silences `logger.debug`). `console.error` bypasses all logger configuration and writes directly to stderr. This is counterintuitive but critical — the one time you NEED debug output is exactly when loggers are configured to hide it.
94
+
95
+ #### Defense-in-Depth (After Root Cause Found)
96
+ When the root cause is invalid data flowing through multiple layers, recommend fixing at ALL layers — not just the source:
97
+
98
+ | Layer | Purpose | Example |
99
+ |-------|---------|---------|
100
+ | Layer 1: Entry Point | Reject invalid input at API/CLI boundary | Validate not empty, exists, correct type |
101
+ | Layer 2: Business Logic | Ensure data makes sense for the operation | Validate required params before processing |
102
+ | Layer 3: Environment Guards | Prevent dangerous operations in specific contexts | Refuse destructive ops outside allowed dirs |
103
+ | Layer 4: Debug Instrumentation | Capture context for forensics | Stack trace logging before dangerous operations |
104
+
105
+ All four layers are necessary. During testing, each layer catches bugs the others miss — different code paths bypass single validation points. When recommending a fix via `rune:fix`, explicitly call out which layers need validation added.
106
+
92
107
  #### Multi-Component Instrumentation (for systems with 3+ layers)
93
108
 
94
109
  When the system has multiple components (CI → build → deploy, API → service → DB):
@@ -3,7 +3,7 @@ name: skill-forge
3
3
  description: Use when creating new Rune skills, editing existing skills, or verifying skill quality before deployment. Applies TDD discipline to skill authoring — test before write, verify before ship.
4
4
  metadata:
5
5
  author: runedev
6
- version: "1.1.0"
6
+ version: "1.2.0"
7
7
  layer: L2
8
8
  model: opus
9
9
  group: creation
@@ -214,6 +214,62 @@ Run additional pressure scenarios with varied pressures. For each new failure:
214
214
 
215
215
  Repeat until no new failures emerge in 2 consecutive test runs.
216
216
 
217
+ #### Pressure Types for Test Scenarios
218
+
219
+ Best tests combine 3+ pressures simultaneously:
220
+
221
+ | Pressure | Example Scenario |
222
+ |----------|------------------|
223
+ | Time | "Emergency deployment, deadline in 30 min" |
224
+ | Sunk cost | "Already wrote 200 lines, can't restart" |
225
+ | Authority | "Senior dev says skip testing" |
226
+ | Economic | "Customer churning, ship now or lose $50k MRR" |
227
+ | Exhaustion | "50 tool calls deep, context filling up" |
228
+ | Social | "Looking dogmatic by insisting on process" |
229
+ | Pragmatic | "Being practical vs being pedantic" |
230
+
231
+ #### Scenario Quality Requirements
232
+
233
+ 1. **Concrete A/B/C options** — force explicit choice (no "I'd ask the user" escape hatch)
234
+ 2. **Real constraints** — specific times, actual consequences, named files
235
+ 3. **Real file paths** — `/tmp/payment-system` not "a project"
236
+ 4. **"Make agent ACT"** — "What do you do?" not "What should you do?"
237
+ 5. **No easy outs** — every option has a cost
238
+
239
+ #### Meta-Testing (When GREEN Isn't Working)
240
+
241
+ If the agent keeps failing even WITH the skill loaded, ask: "How could that skill have been written differently to make the correct option crystal clear?"
242
+
243
+ Three possible responses:
244
+ 1. "Skill was clear, I chose to ignore it" → foundational principle needed (stronger HARD-GATE)
245
+ 2. "Skill should have said X explicitly" → add that exact phrasing verbatim
246
+ 3. "I didn't see section Y" → reorganize for discoverability (move up, add header)
247
+
248
+ #### Bulletproof Criteria
249
+
250
+ A skill is bulletproof when:
251
+ - Agent chooses correct option under maximum pressure (3+ pressures combined)
252
+ - Agent CITES skill sections as justification for its choice
253
+ - Agent ACKNOWLEDGES the temptation but follows the rule anyway
254
+
255
+ #### Persuasion Principles for Skill Language
256
+
257
+ Research (Meincke et al., 2025, 28,000 conversations) shows 33% → 72% compliance with these techniques:
258
+
259
+ | Principle | Application | Use For |
260
+ |-----------|-------------|---------|
261
+ | Authority | "YOU MUST", imperative language | Eliminates decision fatigue, safety-critical rules |
262
+ | Commitment | Explicit announcements + tracked choices | Creates accountability trail |
263
+ | Scarcity | Time-bound requirements, "before proceeding" | Triggers immediate action |
264
+ | Social Proof | "Every time", universal statements | Documents what prevents failures |
265
+ | Unity | "We're building quality" language | Shared identity, quality goals |
266
+
267
+ **Prohibited in skills:**
268
+ - **Liking** ("Great job following the process!") → creates sycophancy
269
+ - **Reciprocity** ("I helped you, now follow the rules") → feels manipulative
270
+
271
+ **Ethical test**: Would this serve the user's genuine interests if they fully understood the technique?
272
+
217
273
  ### Phase 6 — INTEGRATE
218
274
 
219
275
  Wire the skill into the mesh:
@@ -3,7 +3,7 @@ name: test
3
3
  description: "TDD test writer. Writes failing tests FIRST (red), then verifies they pass after implementation (green). Covers unit, integration, and e2e tests."
4
4
  metadata:
5
5
  author: runedev
6
- version: "0.3.0"
6
+ version: "0.4.0"
7
7
  layer: L2
8
8
  model: sonnet
9
9
  group: development
@@ -271,6 +271,36 @@ If you catch yourself with ANY of these, delete implementation code and restart
271
271
  - [existing test that broke, with error details]
272
272
  ```
273
273
 
274
+ ## Testing Anti-Patterns (Gate Functions)
275
+
276
+ Before writing tests, check yourself against these 5 anti-patterns. Each has a **gate function** — a question you MUST answer before proceeding.
277
+
278
+ ### Anti-Pattern 1: Testing Mock Behavior
279
+ Asserting that a mock exists (e.g., `testId="sidebar-mock"`) instead of testing real component behavior. You're proving the mock works, not the code.
280
+ **Gate**: "Am I testing real component behavior or just mock existence?" → If mock existence: STOP. Rewrite to test real behavior.
281
+
282
+ ### Anti-Pattern 2: Test-Only Methods in Production
283
+ Adding `destroy()`, `reset()`, or `__testSetup()` methods to production classes that are ONLY called from test files. Production code should not know tests exist.
284
+ **Gate**: "Is this method only called by tests?" → If yes: STOP. Move to test utilities or test helper file, not production class.
285
+
286
+ ### Anti-Pattern 3: Mocking Without Understanding Side Effects
287
+ Mocking a function without first understanding ALL its side effects. The real function may write config files, update caches, or emit events that downstream code depends on.
288
+ **Gate**: Before mocking, STOP and answer: "What side effects does the REAL function have? Does this test depend on any of those?" → Run with real implementation first, observe what happens, THEN add minimal mocking.
289
+
290
+ ### Anti-Pattern 4: Incomplete Mocks
291
+ Partial mock missing fields that downstream code consumes. Your test passes because it only checks the fields you mocked, but production code reads fields your mock doesn't have → runtime crash.
292
+ **Iron Rule**: Mock the COMPLETE data structure as it exists in reality, not just fields your immediate test uses. Examine actual API response / real data shape before writing mock.
293
+
294
+ ### Anti-Pattern 5: Mock Setup Longer Than Test Logic
295
+ If mock setup is 30 lines and the actual test assertion is 3 lines, the test is testing infrastructure, not behavior. This is a code smell that indicates wrong abstraction level.
296
+ **Gate**: "Is my mock setup longer than my test logic?" → If yes: test at a higher level (integration) or extract mock factories.
297
+
298
+ **Red flags — any of these means STOP and rethink:**
299
+ - Mock setup longer than test logic
300
+ - `*-mock` test IDs in assertions
301
+ - Methods only called in test files
302
+ - Can't explain in one sentence why a mock is needed
303
+
274
304
  ## Sharp Edges
275
305
 
276
306
  Known failure modes for this skill. Check these before declaring done.
@@ -279,10 +309,13 @@ Known failure modes for this skill. Check these before declaring done.
279
309
  |---|---|---|
280
310
  | Tests passing before implementation exists | CRITICAL | RED Gate: rewrite stricter tests — passing without code = not testing real behavior |
281
311
  | Skipping the RED phase (not confirming FAIL) | HIGH | Run tests, confirm FAIL output before calling cook/fix to implement |
282
- | Testing mock behavior instead of real code | HIGH | Constraint 4: test what the real code does, not what the mock returns |
312
+ | Testing mock behavior instead of real code | HIGH | Anti-Pattern 1 gate: "Am I testing real behavior or mock existence?" |
313
+ | Mocking without understanding side effects | HIGH | Anti-Pattern 3 gate: run with real impl first, observe side effects, THEN mock minimally |
314
+ | Incomplete mocks missing downstream fields | HIGH | Anti-Pattern 4 iron rule: mock COMPLETE data structure, not just fields your test checks |
283
315
  | Coverage below 80% without filling gaps | MEDIUM | Coverage Gate: identify uncovered lines and write additional tests |
284
316
  | Introducing a new test framework instead of using existing one | MEDIUM | Constraint 6: detect framework first, use project's existing one always |
285
317
  | Modifying source files to make tests work | HIGH | Role boundary: test writes test files ONLY — source changes go to rune:fix |
318
+ | Test-only methods leaking into production code | MEDIUM | Anti-Pattern 2 gate: if method only called by tests → move to test utilities |
286
319
 
287
320
  ## Done When
288
321