@rune-kit/rune 2.1.1
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 +357 -0
- package/agents/.gitkeep +0 -0
- package/agents/architect.md +29 -0
- package/agents/asset-creator.md +11 -0
- package/agents/audit.md +11 -0
- package/agents/autopsy.md +11 -0
- package/agents/brainstorm.md +11 -0
- package/agents/browser-pilot.md +11 -0
- package/agents/coder.md +29 -0
- package/agents/completion-gate.md +11 -0
- package/agents/constraint-check.md +11 -0
- package/agents/context-engine.md +11 -0
- package/agents/cook.md +11 -0
- package/agents/db.md +11 -0
- package/agents/debug.md +11 -0
- package/agents/dependency-doctor.md +11 -0
- package/agents/deploy.md +11 -0
- package/agents/design.md +11 -0
- package/agents/docs-seeker.md +11 -0
- package/agents/fix.md +11 -0
- package/agents/hallucination-guard.md +11 -0
- package/agents/incident.md +11 -0
- package/agents/integrity-check.md +11 -0
- package/agents/journal.md +11 -0
- package/agents/launch.md +11 -0
- package/agents/logic-guardian.md +11 -0
- package/agents/marketing.md +11 -0
- package/agents/onboard.md +11 -0
- package/agents/perf.md +11 -0
- package/agents/plan.md +11 -0
- package/agents/preflight.md +11 -0
- package/agents/problem-solver.md +11 -0
- package/agents/rescue.md +11 -0
- package/agents/research.md +11 -0
- package/agents/researcher.md +29 -0
- package/agents/review-intake.md +11 -0
- package/agents/review.md +11 -0
- package/agents/reviewer.md +28 -0
- package/agents/safeguard.md +11 -0
- package/agents/sast.md +11 -0
- package/agents/scanner.md +28 -0
- package/agents/scope-guard.md +11 -0
- package/agents/scout.md +11 -0
- package/agents/sentinel.md +11 -0
- package/agents/sequential-thinking.md +11 -0
- package/agents/session-bridge.md +11 -0
- package/agents/skill-forge.md +11 -0
- package/agents/skill-router.md +11 -0
- package/agents/surgeon.md +11 -0
- package/agents/team.md +11 -0
- package/agents/test.md +11 -0
- package/agents/trend-scout.md +11 -0
- package/agents/verification.md +11 -0
- package/agents/video-creator.md +11 -0
- package/agents/watchdog.md +11 -0
- package/agents/worktree.md +11 -0
- package/commands/.gitkeep +0 -0
- package/commands/rune.md +168 -0
- package/compiler/__tests__/openclaw-adapter.test.js +140 -0
- package/compiler/__tests__/parser.test.js +55 -0
- package/compiler/adapters/antigravity.js +59 -0
- package/compiler/adapters/claude.js +37 -0
- package/compiler/adapters/cursor.js +67 -0
- package/compiler/adapters/generic.js +60 -0
- package/compiler/adapters/index.js +45 -0
- package/compiler/adapters/openclaw.js +150 -0
- package/compiler/adapters/windsurf.js +60 -0
- package/compiler/bin/rune.js +288 -0
- package/compiler/doctor.js +153 -0
- package/compiler/emitter.js +240 -0
- package/compiler/parser.js +208 -0
- package/compiler/transformer.js +69 -0
- package/compiler/transforms/branding.js +27 -0
- package/compiler/transforms/cross-references.js +29 -0
- package/compiler/transforms/frontmatter.js +38 -0
- package/compiler/transforms/hooks.js +68 -0
- package/compiler/transforms/subagents.js +36 -0
- package/compiler/transforms/tool-names.js +60 -0
- package/contexts/dev.md +34 -0
- package/contexts/research.md +43 -0
- package/contexts/review.md +55 -0
- package/extensions/ai-ml/PACK.md +517 -0
- package/extensions/analytics/PACK.md +557 -0
- package/extensions/backend/PACK.md +678 -0
- package/extensions/chrome-ext/PACK.md +995 -0
- package/extensions/content/PACK.md +381 -0
- package/extensions/devops/PACK.md +520 -0
- package/extensions/ecommerce/PACK.md +280 -0
- package/extensions/gamedev/PACK.md +393 -0
- package/extensions/mobile/PACK.md +273 -0
- package/extensions/saas/PACK.md +805 -0
- package/extensions/security/PACK.md +536 -0
- package/extensions/trading/PACK.md +597 -0
- package/extensions/ui/PACK.md +947 -0
- package/package.json +47 -0
- package/skills/.gitkeep +0 -0
- package/skills/adversary/SKILL.md +271 -0
- package/skills/asset-creator/SKILL.md +157 -0
- package/skills/audit/SKILL.md +466 -0
- package/skills/autopsy/SKILL.md +200 -0
- package/skills/ba/SKILL.md +279 -0
- package/skills/brainstorm/SKILL.md +266 -0
- package/skills/browser-pilot/SKILL.md +168 -0
- package/skills/completion-gate/SKILL.md +151 -0
- package/skills/constraint-check/SKILL.md +165 -0
- package/skills/context-engine/SKILL.md +176 -0
- package/skills/cook/SKILL.md +636 -0
- package/skills/db/SKILL.md +256 -0
- package/skills/debug/SKILL.md +240 -0
- package/skills/dependency-doctor/SKILL.md +235 -0
- package/skills/deploy/SKILL.md +174 -0
- package/skills/design/DESIGN-REFERENCE.md +365 -0
- package/skills/design/SKILL.md +462 -0
- package/skills/doc-processor/SKILL.md +254 -0
- package/skills/docs/SKILL.md +336 -0
- package/skills/docs-seeker/SKILL.md +166 -0
- package/skills/fix/SKILL.md +192 -0
- package/skills/git/SKILL.md +285 -0
- package/skills/hallucination-guard/SKILL.md +204 -0
- package/skills/incident/SKILL.md +241 -0
- package/skills/integrity-check/SKILL.md +169 -0
- package/skills/journal/SKILL.md +190 -0
- package/skills/launch/SKILL.md +330 -0
- package/skills/logic-guardian/SKILL.md +240 -0
- package/skills/marketing/SKILL.md +229 -0
- package/skills/mcp-builder/SKILL.md +311 -0
- package/skills/onboard/SKILL.md +298 -0
- package/skills/perf/SKILL.md +297 -0
- package/skills/plan/SKILL.md +520 -0
- package/skills/preflight/SKILL.md +231 -0
- package/skills/problem-solver/SKILL.md +284 -0
- package/skills/rescue/SKILL.md +434 -0
- package/skills/research/SKILL.md +122 -0
- package/skills/review/SKILL.md +354 -0
- package/skills/review-intake/SKILL.md +222 -0
- package/skills/safeguard/SKILL.md +188 -0
- package/skills/sast/SKILL.md +190 -0
- package/skills/scaffold/SKILL.md +276 -0
- package/skills/scope-guard/SKILL.md +150 -0
- package/skills/scout/SKILL.md +232 -0
- package/skills/sentinel/SKILL.md +320 -0
- package/skills/sentinel-env/SKILL.md +226 -0
- package/skills/sequential-thinking/SKILL.md +234 -0
- package/skills/session-bridge/SKILL.md +287 -0
- package/skills/skill-forge/SKILL.md +317 -0
- package/skills/skill-router/SKILL.md +267 -0
- package/skills/surgeon/SKILL.md +203 -0
- package/skills/team/SKILL.md +397 -0
- package/skills/test/SKILL.md +271 -0
- package/skills/trend-scout/SKILL.md +145 -0
- package/skills/verification/SKILL.md +201 -0
- package/skills/video-creator/SKILL.md +201 -0
- package/skills/watchdog/SKILL.md +166 -0
- package/skills/worktree/SKILL.md +140 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sentinel
|
|
3
|
+
description: Automated security gatekeeper. Blocks unsafe code before commit — secret scanning, OWASP top 10, dependency audit, permission checks. A GATE, not a suggestion.
|
|
4
|
+
metadata:
|
|
5
|
+
author: runedev
|
|
6
|
+
version: "0.2.0"
|
|
7
|
+
layer: L2
|
|
8
|
+
model: sonnet
|
|
9
|
+
group: quality
|
|
10
|
+
tools: "Read, Bash, Glob, Grep"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# sentinel
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Automated security gatekeeper that blocks unsafe code BEFORE commit. Unlike `review` which suggests improvements, sentinel is a hard gate — it BLOCKS on critical findings. Runs secret scanning, OWASP top 10 pattern detection, dependency auditing, and destructive command checks. Escalates to opus for deep security audit when critical patterns detected.
|
|
18
|
+
|
|
19
|
+
<HARD-GATE>
|
|
20
|
+
If status is BLOCK, output the report and STOP. Do not hand off to commit. The calling skill (`cook`, `preflight`, `deploy`) must halt until the developer fixes all BLOCK findings and re-runs sentinel.
|
|
21
|
+
</HARD-GATE>
|
|
22
|
+
|
|
23
|
+
## Triggers
|
|
24
|
+
|
|
25
|
+
- Called automatically by `cook` before commit phase
|
|
26
|
+
- Called by `preflight` as security sub-check
|
|
27
|
+
- Called by `deploy` before deployment
|
|
28
|
+
- `/rune sentinel` — manual security scan
|
|
29
|
+
- Auto-trigger: when `.env`, auth files, or security-critical code is modified
|
|
30
|
+
|
|
31
|
+
## Calls (outbound)
|
|
32
|
+
|
|
33
|
+
- `scout` (L2): scan changed files to identify security-relevant code
|
|
34
|
+
- `verification` (L3): run security tools (npm audit, pip audit, cargo audit)
|
|
35
|
+
- `integrity-check` (L3): agentic security validation of .rune/ state files
|
|
36
|
+
- `sast` (L3): deep static analysis with Semgrep, Bandit, ESLint security rules
|
|
37
|
+
|
|
38
|
+
## Called By (inbound)
|
|
39
|
+
|
|
40
|
+
- `cook` (L1): auto-trigger before commit phase
|
|
41
|
+
- `review` (L2): when security-critical code detected
|
|
42
|
+
- `deploy` (L2): pre-deployment security check
|
|
43
|
+
- `preflight` (L2): security sub-check in quality gate
|
|
44
|
+
- `audit` (L2): Phase 2 full security audit
|
|
45
|
+
- `incident` (L2): security dimension check during incident response
|
|
46
|
+
- `review-intake` (L2): security scan on code submitted for structured review
|
|
47
|
+
|
|
48
|
+
## Severity Levels
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
BLOCK — commit MUST NOT proceed (secrets found, critical CVE, SQL injection)
|
|
52
|
+
WARN — commit can proceed but developer must acknowledge (medium CVE, missing validation)
|
|
53
|
+
INFO — informational finding, no action required (best practice suggestion)
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Security Patterns (built-in)
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
# Secret patterns (regex)
|
|
60
|
+
AWS_KEY: AKIA[0-9A-Z]{16}
|
|
61
|
+
GITHUB_TOKEN: gh[ps]_[A-Za-z0-9_]{36,}
|
|
62
|
+
GENERIC_SECRET: (?i)(api[_-]?key|secret|password|token)\s*[:=]\s*["'][^"']{8,}
|
|
63
|
+
HIGH_ENTROPY: [A-Za-z0-9+/=]{40,} (entropy > 4.5)
|
|
64
|
+
|
|
65
|
+
# OWASP patterns
|
|
66
|
+
SQL_INJECTION: string concat/interpolation in SQL context
|
|
67
|
+
XSS: innerHTML, dangerouslySetInnerHTML, document.write
|
|
68
|
+
CSRF: form without CSRF token, missing SameSite cookie
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Executable Steps
|
|
72
|
+
|
|
73
|
+
### Step 1 — Secret Scan (Gitleaks-Enhanced)
|
|
74
|
+
|
|
75
|
+
Use `Grep` to search all changed files (or full codebase if no diff available) for secret patterns.
|
|
76
|
+
|
|
77
|
+
**1a. Current file scan:**
|
|
78
|
+
- Patterns: `sk-`, `AKIA`, `ghp_`, `ghs_`, `-----BEGIN`, `password\s*=\s*["']`, `secret\s*=\s*["']`, `api_key\s*=\s*["']`, `token\s*=\s*["']`
|
|
79
|
+
- Also scan for `.env` file contents committed directly (grep for lines matching `KEY=value` outside `.env` files)
|
|
80
|
+
- Flag any string with entropy > 4.5 and length > 40 characters as HIGH_ENTROPY candidate
|
|
81
|
+
|
|
82
|
+
**1b. Extended gitleaks patterns:**
|
|
83
|
+
```
|
|
84
|
+
SLACK_TOKEN: xox[bpors]-[0-9a-zA-Z]{10,}
|
|
85
|
+
STRIPE_KEY: [sr]k_(live|test)_[0-9a-zA-Z]{24,}
|
|
86
|
+
SENDGRID: SG\.[a-zA-Z0-9_-]{22}\.[a-zA-Z0-9_-]{43}
|
|
87
|
+
TWILIO: SK[0-9a-fA-F]{32}
|
|
88
|
+
FIREBASE: AIza[0-9A-Za-z_-]{35}
|
|
89
|
+
PRIVATE_KEY: -----BEGIN (RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----
|
|
90
|
+
JWT: eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}
|
|
91
|
+
GENERIC_API_KEY: (?i)(apikey|api_key|api-key)\s*[:=]\s*["'][A-Za-z0-9_-]{16,}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**1c. Git history scan (first run only):**
|
|
95
|
+
If this is the first sentinel scan on this repo (no `.rune/sentinel-baseline.md` exists):
|
|
96
|
+
```
|
|
97
|
+
Bash: git log --all --diff-filter=A -- '*.env*' '*.key' '*.pem' '*.p12' '*credentials*' '*secret*'
|
|
98
|
+
→ If any results: WARN — historical secret files detected. Recommend BFG/git-filter-repo cleanup.
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
For subsequent runs, scan only the current diff (incremental).
|
|
102
|
+
|
|
103
|
+
Any match = **BLOCK**. Do not proceed to later steps if BLOCK findings exist — report immediately.
|
|
104
|
+
|
|
105
|
+
### Step 2 — Dependency Audit
|
|
106
|
+
Use `Bash` to run the appropriate audit command for the detected package manager:
|
|
107
|
+
- npm/pnpm/yarn: `npm audit --json` (parse JSON, extract critical + high severity)
|
|
108
|
+
- Python: `pip-audit --format=json` (if installed) or `safety check`
|
|
109
|
+
- Rust: `cargo audit --json`
|
|
110
|
+
- Go: `govulncheck ./...`
|
|
111
|
+
|
|
112
|
+
Critical CVE (CVSS >= 9.0) = **BLOCK**. High CVE (CVSS 7.0–8.9) = **WARN**. Medium/Low = **INFO**.
|
|
113
|
+
|
|
114
|
+
If audit tool is not installed, log **INFO**: "audit tool not found, skipping dependency check" — do NOT block on missing tooling.
|
|
115
|
+
|
|
116
|
+
### Step 3 — OWASP Check
|
|
117
|
+
Use `Read` to scan changed files for:
|
|
118
|
+
- **SQL Injection**: string concatenation or interpolation inside SQL query strings (e.g., `"SELECT * FROM users WHERE id = " + userId`, f-strings with SQL). Flag = **BLOCK**
|
|
119
|
+
- **XSS**: `innerHTML =`, `dangerouslySetInnerHTML`, `document.write(` with non-static content. Flag = **BLOCK**
|
|
120
|
+
- **CSRF**: HTML `<form>` elements without CSRF token fields; `Set-Cookie` headers without `SameSite`. Flag = **WARN**
|
|
121
|
+
- **Missing input validation**: new route handlers or API endpoints that directly pass `req.body` / `request.json()` to a database call without a validation schema. Flag = **WARN**
|
|
122
|
+
|
|
123
|
+
**SQL Injection examples:**
|
|
124
|
+
```python
|
|
125
|
+
# BAD — string interpolation in SQL → BLOCK
|
|
126
|
+
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
|
|
127
|
+
query = "SELECT * FROM users WHERE name = '" + name + "'"
|
|
128
|
+
# GOOD — parameterized query
|
|
129
|
+
cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
**XSS examples:**
|
|
133
|
+
```typescript
|
|
134
|
+
// BAD — renders raw user content → BLOCK
|
|
135
|
+
element.innerHTML = userComment;
|
|
136
|
+
<div dangerouslySetInnerHTML={{ __html: userInput }} />
|
|
137
|
+
// GOOD — safe alternatives
|
|
138
|
+
element.textContent = userComment;
|
|
139
|
+
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(userInput) }} />
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**Input validation examples:**
|
|
143
|
+
```typescript
|
|
144
|
+
// BAD — raw body to DB → WARN
|
|
145
|
+
app.post('/users', async (req, res) => { await db.users.create(req.body); });
|
|
146
|
+
// GOOD — validate at boundary
|
|
147
|
+
app.post('/users', async (req, res) => {
|
|
148
|
+
const validated = CreateUserSchema.parse(req.body);
|
|
149
|
+
await db.users.create(validated);
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Step 4 — Permission Check
|
|
154
|
+
Use `Grep` to scan for:
|
|
155
|
+
- Destructive shell commands in scripts: `rm -rf /`, `DROP TABLE`, `DELETE FROM` without `WHERE`, `TRUNCATE`
|
|
156
|
+
- File operations using absolute paths outside the project root (e.g., `/etc/`, `/usr/`, `C:\Windows\`)
|
|
157
|
+
- Direct production database connection strings (e.g., `prod`, `production` in DB host names)
|
|
158
|
+
|
|
159
|
+
Destructive command on production path = **BLOCK**. Suspicious path = **WARN**.
|
|
160
|
+
|
|
161
|
+
### Step 4.5 — Framework-Specific Security Patterns
|
|
162
|
+
|
|
163
|
+
Apply only if the framework is detected in changed files:
|
|
164
|
+
|
|
165
|
+
**Django** (detect: `django` in requirements or imports)
|
|
166
|
+
- `DEBUG = True` in non-development settings → **BLOCK**
|
|
167
|
+
- Missing `permission_classes` on ModelViewSet → **WARN**
|
|
168
|
+
- CSRF middleware removed from `MIDDLEWARE` list → **BLOCK**
|
|
169
|
+
|
|
170
|
+
**React / Next.js** (detect: `.tsx` / `.jsx` files)
|
|
171
|
+
- JWT stored in `localStorage` instead of `httpOnly` cookie → **WARN**
|
|
172
|
+
- `dangerouslySetInnerHTML` without `DOMPurify.sanitize()` → **BLOCK**
|
|
173
|
+
|
|
174
|
+
**Node.js / Express / Fastify** (detect: `express`, `fastify` imports)
|
|
175
|
+
- CORS set to `origin: '*'` on authenticated endpoints → **WARN**
|
|
176
|
+
- Missing `helmet` middleware for HTTP security headers → **WARN**
|
|
177
|
+
|
|
178
|
+
**Python** (detect: `.py` files)
|
|
179
|
+
- `pickle.loads(user_input)` or `eval(user_expression)` → **BLOCK**
|
|
180
|
+
- `yaml.load()` without `Loader` arg (uses unsafe loader) → **WARN**
|
|
181
|
+
|
|
182
|
+
### Step 4.6 — Config Protection (3-Layer Defense)
|
|
183
|
+
|
|
184
|
+
Detect attempts to weaken code quality or security configurations. Agents and developers sometimes disable checks to "fix" build errors — sentinel blocks this.
|
|
185
|
+
|
|
186
|
+
**Layer 1 — Linter/Formatter Config Drift:**
|
|
187
|
+
Scan diff for changes to these files:
|
|
188
|
+
- `.eslintrc*`, `eslint.config.*`, `biome.json` → rules disabled or removed
|
|
189
|
+
- `tsconfig.json` → `strict` changed to `false`, `any` allowed, `skipLibCheck` added
|
|
190
|
+
- `ruff.toml`, `.ruff.toml`, `pyproject.toml [tool.ruff]` → rules removed from select list
|
|
191
|
+
- `.prettierrc*` → significant format changes without team discussion
|
|
192
|
+
|
|
193
|
+
Detection patterns:
|
|
194
|
+
```
|
|
195
|
+
# ESLint rule disable
|
|
196
|
+
"off" or 0 in rule config (compare with previous)
|
|
197
|
+
// eslint-disable added to >3 lines in same file
|
|
198
|
+
|
|
199
|
+
# TypeScript strictness weakening
|
|
200
|
+
"strict": false
|
|
201
|
+
"noImplicitAny": false
|
|
202
|
+
"skipLibCheck": true (added, not already present)
|
|
203
|
+
|
|
204
|
+
# Ruff rule removal
|
|
205
|
+
select = [...] with fewer rules than before
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Match = **WARN** with message: "Config change weakens code quality — verify this is intentional."
|
|
209
|
+
|
|
210
|
+
**Layer 2 — Security Middleware Removal:**
|
|
211
|
+
Scan for removal of security-critical middleware/imports:
|
|
212
|
+
- `helmet` removed from Express/Fastify middleware chain
|
|
213
|
+
- `csrf` middleware removed or commented out
|
|
214
|
+
- `cors` configuration changed to `origin: '*'`
|
|
215
|
+
- `SecurityMiddleware` removed from Django `MIDDLEWARE`
|
|
216
|
+
- `@csrf_protect` decorator removed from Django views
|
|
217
|
+
|
|
218
|
+
Match = **BLOCK** with message: "Security middleware removed — this must be explicitly justified."
|
|
219
|
+
|
|
220
|
+
**Layer 3 — CI/CD Safety Bypass:**
|
|
221
|
+
Scan for weakening of CI/CD safety checks:
|
|
222
|
+
- `--no-verify` added to git commands in scripts
|
|
223
|
+
- `--force` added to deployment scripts
|
|
224
|
+
- Test steps removed or marked `continue-on-error: true`
|
|
225
|
+
- Coverage thresholds lowered
|
|
226
|
+
|
|
227
|
+
Match = **WARN** with message: "CI safety check weakened — verify this is intentional."
|
|
228
|
+
|
|
229
|
+
### Step 4.7 — Agentic Security Scan
|
|
230
|
+
|
|
231
|
+
If `.rune/` directory exists in the project, invoke `integrity-check` (L3) to scan for adversarial content:
|
|
232
|
+
|
|
233
|
+
```
|
|
234
|
+
REQUIRED SUB-SKILL: rune:integrity-check
|
|
235
|
+
→ Invoke integrity-check on all .rune/*.md files + any state files in the commit diff.
|
|
236
|
+
→ Capture: status (CLEAN | SUSPICIOUS | TAINTED), findings list.
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Map integrity-check results to sentinel severity:
|
|
240
|
+
- `TAINTED` → sentinel **BLOCK** (adversarial content in state files)
|
|
241
|
+
- `SUSPICIOUS` → sentinel **WARN** (review recommended before commit)
|
|
242
|
+
- `CLEAN` → no additional findings
|
|
243
|
+
|
|
244
|
+
If `.rune/` directory does not exist, skip this step (log INFO: "no .rune/ state files, agentic scan skipped").
|
|
245
|
+
|
|
246
|
+
### Step 5 — Report
|
|
247
|
+
Aggregate all findings. Apply the verdict rule:
|
|
248
|
+
- Any **BLOCK** finding → overall status = **BLOCK**. List all BLOCK items first.
|
|
249
|
+
- No BLOCK but any **WARN** → overall status = **WARN**. Developer must acknowledge each WARN.
|
|
250
|
+
- Only **INFO** → overall status = **PASS**.
|
|
251
|
+
|
|
252
|
+
If status is BLOCK, output the report and STOP. Do not hand off to commit. The calling skill (`cook`, `preflight`, `deploy`) must halt until the developer fixes all BLOCK findings and re-runs sentinel.
|
|
253
|
+
|
|
254
|
+
### WARN Acknowledgment Protocol
|
|
255
|
+
|
|
256
|
+
WARN findings do not block the commit but MUST be explicitly acknowledged:
|
|
257
|
+
|
|
258
|
+
```
|
|
259
|
+
For each WARN item, developer must respond with one of:
|
|
260
|
+
- "ack" — acknowledged, will fix later (logged to .rune/decisions.md)
|
|
261
|
+
- "fix" — fixing now (sentinel re-runs after fix)
|
|
262
|
+
- "wontfix [reason]" — intentional, with documented reason
|
|
263
|
+
|
|
264
|
+
Silent continuation past WARN = VIOLATION.
|
|
265
|
+
The calling skill (cook) must present WARNs and wait for acknowledgment.
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Output Format
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
## Sentinel Report
|
|
272
|
+
- **Status**: PASS | WARN | BLOCK
|
|
273
|
+
- **Files Scanned**: [count]
|
|
274
|
+
- **Findings**: [count by severity]
|
|
275
|
+
|
|
276
|
+
### BLOCK (must fix before commit)
|
|
277
|
+
- `path/to/file.ts:42` — Hardcoded API key detected (pattern: sk-...)
|
|
278
|
+
- `path/to/api.ts:15` — SQL injection: string concatenation in query
|
|
279
|
+
|
|
280
|
+
### WARN (must acknowledge)
|
|
281
|
+
- `package.json` — lodash@4.17.20 has known prototype pollution (CVE-2021-23337, CVSS 7.4)
|
|
282
|
+
|
|
283
|
+
### INFO
|
|
284
|
+
- `auth.ts:30` — Consider adding rate limiting to login endpoint
|
|
285
|
+
|
|
286
|
+
### Verdict
|
|
287
|
+
BLOCKED — 2 critical findings must be resolved before commit.
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## Constraints
|
|
291
|
+
|
|
292
|
+
1. MUST scan ALL files in scope — not just the file the user pointed at
|
|
293
|
+
2. MUST check: hardcoded secrets, SQL injection, XSS, CSRF, auth bypass, path traversal
|
|
294
|
+
3. MUST list every file checked in the report — "no issues found" requires proof of what was examined
|
|
295
|
+
4. MUST NOT say "the framework handles security" as justification for skipping checks
|
|
296
|
+
5. MUST NOT say "this is an internal tool" as justification for reduced security
|
|
297
|
+
6. MUST flag any .env, credentials, or key files found in git-tracked directories
|
|
298
|
+
7. MUST use opus model for security-critical code (auth, crypto, payments)
|
|
299
|
+
|
|
300
|
+
## Sharp Edges
|
|
301
|
+
|
|
302
|
+
| Failure Mode | Severity | Mitigation |
|
|
303
|
+
|---|---|---|
|
|
304
|
+
| False positive on test fixtures with fake secrets | MEDIUM | Verify file path — `test/`, `fixtures/`, `__mocks__/` patterns; check string entropy |
|
|
305
|
+
| Skipping framework checks because "the framework handles it" | HIGH | CONSTRAINT blocks this rationalization — apply checks regardless |
|
|
306
|
+
| Dependency audit tool missing → silently skipped | LOW | Report INFO "tool not found, skipping" — never skip silently |
|
|
307
|
+
| Stopping after first BLOCK without aggregating all findings | MEDIUM | Complete ALL steps, aggregate ALL findings, then report — developer needs the full list |
|
|
308
|
+
| Missing agentic security scan when .rune/ exists | HIGH | Step 4.7 is mandatory when .rune/ directory detected — never skip |
|
|
309
|
+
|
|
310
|
+
## Done When
|
|
311
|
+
|
|
312
|
+
- All files in scope scanned for secret patterns
|
|
313
|
+
- OWASP checks applied (SQL injection, XSS, CSRF, input validation)
|
|
314
|
+
- Dependency audit ran (or "tool not found" reported as INFO)
|
|
315
|
+
- Framework-specific checks applied for every detected framework
|
|
316
|
+
- Structured report emitted with PASS / WARN / BLOCK verdict and all files scanned listed
|
|
317
|
+
|
|
318
|
+
## Cost Profile
|
|
319
|
+
|
|
320
|
+
~1000-3000 tokens input, ~500-1000 tokens output. Sonnet default, opus for deep audit on critical findings.
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sentinel-env
|
|
3
|
+
description: Environment-aware pre-flight check. Validates OS, runtime versions, installed tools, port availability, env vars, and disk space BEFORE coding starts. Prevents "works on my machine" failures. Like sentinel but for the environment, not the code.
|
|
4
|
+
metadata:
|
|
5
|
+
author: runedev
|
|
6
|
+
version: "0.1.0"
|
|
7
|
+
layer: L3
|
|
8
|
+
model: haiku
|
|
9
|
+
group: validation
|
|
10
|
+
tools: "Bash, Read, Glob, Grep"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# sentinel-env
|
|
14
|
+
|
|
15
|
+
## Purpose
|
|
16
|
+
|
|
17
|
+
Catch environment mismatches before they waste debugging time. Validates that the developer's machine has the right runtime versions, tools, ports, and configuration to run the project. Prevents the entire class of "works on my machine" failures that masquerade as code bugs.
|
|
18
|
+
|
|
19
|
+
This is the environment counterpart to `sentinel` (which checks code security) and `preflight` (which checks code quality). sentinel-env checks the MACHINE, not the code.
|
|
20
|
+
|
|
21
|
+
## Triggers
|
|
22
|
+
|
|
23
|
+
- Called by `cook` Phase 0.5 — before planning, after resume check (first run in a new project only)
|
|
24
|
+
- Called by `scaffold` — after project bootstrap, verify environment matches generated config
|
|
25
|
+
- Called by `onboard` — during project onboarding, verify developer can run the project
|
|
26
|
+
- `/rune env-check` — manual environment validation
|
|
27
|
+
- Auto-trigger: when `npm install`, `pip install`, or similar fails during cook
|
|
28
|
+
|
|
29
|
+
## Calls (outbound)
|
|
30
|
+
|
|
31
|
+
None — sentinel-env is a pure read-only utility. It checks and reports, never modifies.
|
|
32
|
+
|
|
33
|
+
## Called By (inbound)
|
|
34
|
+
|
|
35
|
+
- `cook` (L1): Phase 0.5 — first run detection (no `.rune/` directory exists)
|
|
36
|
+
- `scaffold` (L1): post-bootstrap environment validation
|
|
37
|
+
- `onboard` (L2): developer onboarding verification
|
|
38
|
+
- User: `/rune env-check` direct invocation
|
|
39
|
+
|
|
40
|
+
## Execution
|
|
41
|
+
|
|
42
|
+
### Step 1: Detect Project Type
|
|
43
|
+
|
|
44
|
+
Read project configuration files to determine what environment is needed:
|
|
45
|
+
|
|
46
|
+
1. Use `Glob` to check for project config files:
|
|
47
|
+
- `package.json` → Node.js project
|
|
48
|
+
- `pyproject.toml` / `setup.py` / `requirements.txt` → Python project
|
|
49
|
+
- `Cargo.toml` → Rust project
|
|
50
|
+
- `go.mod` → Go project
|
|
51
|
+
- `Gemfile` → Ruby project
|
|
52
|
+
- `docker-compose.yml` / `Dockerfile` → Docker project
|
|
53
|
+
- `.nvmrc` / `.node-version` → specific Node version required
|
|
54
|
+
- `.python-version` → specific Python version required
|
|
55
|
+
|
|
56
|
+
2. Read each detected config file to extract version constraints:
|
|
57
|
+
- `package.json` → `engines.node`, `engines.npm`, dependency versions
|
|
58
|
+
- `pyproject.toml` → `requires-python`, dependency versions
|
|
59
|
+
- `Cargo.toml` → `rust-version`
|
|
60
|
+
- `go.mod` → `go` directive version
|
|
61
|
+
|
|
62
|
+
3. Build an environment requirements checklist from the detected configs.
|
|
63
|
+
|
|
64
|
+
### Step 2: Runtime Version Check
|
|
65
|
+
|
|
66
|
+
For each detected runtime, verify the installed version matches constraints:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Node.js
|
|
70
|
+
node --version # Compare against package.json engines.node or .nvmrc
|
|
71
|
+
npm --version # Compare against package.json engines.npm
|
|
72
|
+
# or pnpm/yarn/bun depending on lockfile present
|
|
73
|
+
|
|
74
|
+
# Python
|
|
75
|
+
python --version # Compare against pyproject.toml requires-python
|
|
76
|
+
pip --version
|
|
77
|
+
|
|
78
|
+
# Rust
|
|
79
|
+
rustc --version # Compare against Cargo.toml rust-version
|
|
80
|
+
cargo --version
|
|
81
|
+
|
|
82
|
+
# Go
|
|
83
|
+
go version # Compare against go.mod go directive
|
|
84
|
+
|
|
85
|
+
# Docker
|
|
86
|
+
docker --version
|
|
87
|
+
docker compose version
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Version comparison logic:**
|
|
91
|
+
- If the constraint is `>=18.0.0` and installed is `20.11.1` → PASS
|
|
92
|
+
- If the constraint is `>=18.0.0` and installed is `16.20.2` → BLOCK (wrong major version)
|
|
93
|
+
- If the runtime is not installed at all → BLOCK
|
|
94
|
+
- If no version constraint exists in config → WARN (version unconstrained)
|
|
95
|
+
|
|
96
|
+
### Step 3: Required Tools Check
|
|
97
|
+
|
|
98
|
+
Detect and verify tools the project depends on:
|
|
99
|
+
|
|
100
|
+
1. **Package manager**: Check which lockfile exists and verify the matching tool is installed
|
|
101
|
+
- `package-lock.json` → npm
|
|
102
|
+
- `pnpm-lock.yaml` → pnpm
|
|
103
|
+
- `yarn.lock` → yarn
|
|
104
|
+
- `bun.lockb` → bun
|
|
105
|
+
- `poetry.lock` → poetry
|
|
106
|
+
- `uv.lock` → uv
|
|
107
|
+
- Mismatched lockfile + installed tool → WARN (e.g., yarn.lock exists but only npm installed)
|
|
108
|
+
|
|
109
|
+
2. **Git**: `git --version` — required for all projects
|
|
110
|
+
3. **Docker**: Check only if `Dockerfile` or `docker-compose.yml` exists
|
|
111
|
+
4. **Database tools**: Check if `prisma`, `drizzle`, `alembic`, `django` migrations exist → verify DB client installed
|
|
112
|
+
5. **Build tools**: Check for `turbo.json` (turborepo), `nx.json` (Nx), `Makefile`, etc.
|
|
113
|
+
|
|
114
|
+
### Step 4: Port Availability Check
|
|
115
|
+
|
|
116
|
+
Detect which ports the project needs and check if they're available:
|
|
117
|
+
|
|
118
|
+
1. Parse port information from:
|
|
119
|
+
- `package.json` scripts (look for `--port`, `-p`, `PORT=` patterns)
|
|
120
|
+
- `.env` / `.env.example` (look for `PORT=`, `DATABASE_URL` with port)
|
|
121
|
+
- `docker-compose.yml` (ports section)
|
|
122
|
+
- Common defaults: 3000 (Next.js/React), 5173 (Vite), 8000 (Django/FastAPI), 5432 (PostgreSQL), 6379 (Redis)
|
|
123
|
+
|
|
124
|
+
2. Check each port:
|
|
125
|
+
```bash
|
|
126
|
+
# Cross-platform port check
|
|
127
|
+
# Windows: netstat -ano | findstr :PORT
|
|
128
|
+
# Unix: lsof -i :PORT or ss -tlnp | grep :PORT
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
3. If port is in use → WARN with the process name using it
|
|
132
|
+
|
|
133
|
+
### Step 5: Environment Variables Check
|
|
134
|
+
|
|
135
|
+
Compare required env vars against actual configuration:
|
|
136
|
+
|
|
137
|
+
1. Read `.env.example` or `.env.template` if it exists
|
|
138
|
+
2. Read `.env` if it exists (DO NOT log values — only check key presence)
|
|
139
|
+
3. For each key in `.env.example`:
|
|
140
|
+
- Present in `.env` → PASS
|
|
141
|
+
- Missing from `.env` → WARN (with the key name, never the expected value)
|
|
142
|
+
4. Check for dangerous patterns:
|
|
143
|
+
- `.env` committed to git (check `.gitignore`) → BLOCK (security risk)
|
|
144
|
+
- Placeholder values still present (`your-api-key-here`, `changeme`, `xxx`) → WARN
|
|
145
|
+
|
|
146
|
+
### Step 6: Disk Space and System Resources
|
|
147
|
+
|
|
148
|
+
Quick system health check:
|
|
149
|
+
|
|
150
|
+
1. **Disk space**: Check available space on the project drive
|
|
151
|
+
- < 1 GB → WARN
|
|
152
|
+
- < 500 MB → BLOCK (npm install / docker build will fail)
|
|
153
|
+
|
|
154
|
+
2. **Platform-specific checks**:
|
|
155
|
+
- **Windows**: Check for long path support (`git config core.longpaths` for node_modules)
|
|
156
|
+
- **macOS**: Check Xcode CLI tools if native modules detected (`node-gyp` in dependencies)
|
|
157
|
+
- **Linux**: Check file watcher limit if large project (`fs.inotify.max_user_watches`)
|
|
158
|
+
|
|
159
|
+
### Step 7: Report
|
|
160
|
+
|
|
161
|
+
Produce a structured environment report:
|
|
162
|
+
|
|
163
|
+
**Verdict logic:**
|
|
164
|
+
- Any BLOCK finding → **BLOCKED** (environment cannot run this project)
|
|
165
|
+
- Any WARN finding → **READY WITH WARNINGS** (can run but may hit issues)
|
|
166
|
+
- All checks pass → **READY** (environment is correctly configured)
|
|
167
|
+
|
|
168
|
+
For each finding, include a specific remediation command the developer can copy-paste.
|
|
169
|
+
|
|
170
|
+
## Output Format
|
|
171
|
+
|
|
172
|
+
```
|
|
173
|
+
## Environment Check: [project name]
|
|
174
|
+
- **Project type**: [Node.js / Python / Rust / Go / Multi]
|
|
175
|
+
- **Checks run**: [count]
|
|
176
|
+
- **Verdict**: READY | READY WITH WARNINGS | BLOCKED
|
|
177
|
+
|
|
178
|
+
### BLOCKED
|
|
179
|
+
- [ENV-001] Node.js 16.20.2 installed but >=18.0.0 required
|
|
180
|
+
→ Fix: `nvm install 18 && nvm use 18`
|
|
181
|
+
|
|
182
|
+
### WARNINGS
|
|
183
|
+
- [ENV-002] Port 3000 in use by process "node" (PID 12345)
|
|
184
|
+
→ Fix: `kill 12345` or change PORT in .env
|
|
185
|
+
- [ENV-003] Missing env var: DATABASE_URL (required by .env.example)
|
|
186
|
+
→ Fix: Copy from .env.example and fill in your database connection string
|
|
187
|
+
|
|
188
|
+
### PASSED
|
|
189
|
+
- [ENV-004] pnpm 9.1.0 ✓ (matches pnpm-lock.yaml)
|
|
190
|
+
- [ENV-005] Git 2.44.0 ✓
|
|
191
|
+
- [ENV-006] Docker 25.0.3 ✓
|
|
192
|
+
- [ENV-007] Disk space: 42 GB available ✓
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Constraints
|
|
196
|
+
|
|
197
|
+
1. MUST be read-only — never install, update, or modify anything on the developer's machine
|
|
198
|
+
2. MUST NOT log environment variable VALUES — only check key presence (security)
|
|
199
|
+
3. MUST provide copy-paste remediation commands for every BLOCK and WARN finding
|
|
200
|
+
4. MUST handle cross-platform differences (Windows/macOS/Linux) gracefully
|
|
201
|
+
5. MUST complete in under 10 seconds — use parallel Bash calls where possible
|
|
202
|
+
6. MUST NOT block on WARN findings — only BLOCK findings prevent proceeding
|
|
203
|
+
|
|
204
|
+
## Sharp Edges
|
|
205
|
+
|
|
206
|
+
| Failure Mode | Severity | Mitigation |
|
|
207
|
+
|---|---|---|
|
|
208
|
+
| False BLOCK on version — semver parsing error | HIGH | Use simple major.minor comparison, not full semver regex |
|
|
209
|
+
| Slowness on Windows — netstat/port checks are slower | MEDIUM | Timeout port checks at 3s, skip if slow |
|
|
210
|
+
| .env file contains secrets — accidentally logged | CRITICAL | NEVER read .env values, only check key existence via grep for key names |
|
|
211
|
+
| Platform detection wrong — WSL vs native Windows | MEDIUM | Check for WSL explicitly (`uname -r` contains "microsoft") |
|
|
212
|
+
| Over-checking — flagging optional tools as required | MEDIUM | Only check tools evidenced by config files, not speculative |
|
|
213
|
+
|
|
214
|
+
## Done When
|
|
215
|
+
|
|
216
|
+
- All detected project runtimes version-checked against constraints
|
|
217
|
+
- Package manager matches lockfile type
|
|
218
|
+
- Required ports checked for availability
|
|
219
|
+
- Environment variables compared against .env.example (keys only)
|
|
220
|
+
- Disk space verified adequate
|
|
221
|
+
- Structured report with READY / READY WITH WARNINGS / BLOCKED verdict
|
|
222
|
+
- Every BLOCK/WARN finding has a copy-paste remediation command
|
|
223
|
+
|
|
224
|
+
## Cost Profile
|
|
225
|
+
|
|
226
|
+
~500-1000 tokens input, ~500-1000 tokens output. Haiku model — this is fast, cheap, read-only scanning. Runs once per new project (or on manual invoke). Sub-10-second execution target.
|