# Sentinel Env

> Environment-aware pre-flight check. Use when starting work in a new environment, switching machines, or when 'works on my machine' bugs surface. Validates OS, runtime versions, installed tools, port availability, env vars, and disk space BEFORE coding starts. Like sentinel but for the environment, not the code.

- **Type:** Skill
- **Install:** `agentstack add skill-rune-kit-rune-sentinel-env`
- **Verified:** Pending review
- **Seller:** [Rune-kit](https://agentstack.voostack.com/s/rune-kit)
- **Installs:** 0
- **Category:** [Agent Skills](https://agentstack.voostack.com/c/agent-skills)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [Rune-kit](https://github.com/Rune-kit)
- **Source:** https://github.com/Rune-kit/rune/tree/master/skills/sentinel-env

## Install

```sh
agentstack add skill-rune-kit-rune-sentinel-env
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# sentinel-env

## Purpose

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.

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.

## Triggers

- Called by `cook` Phase 0.5 — before planning, after resume check (first run in a new project only)
- Called by `scaffold` — after project bootstrap, verify environment matches generated config
- Called by `onboard` — during project onboarding, verify developer can run the project
- `/rune env-check` — manual environment validation
- Auto-trigger: when `npm install`, `pip install`, or similar fails during cook

## Calls (outbound)

None — sentinel-env is a pure read-only utility. It checks and reports, never modifies.

## Called By (inbound)

- `cook` (L1): Phase 0.5 — first run detection (no `.rune/` directory exists)
- `scaffold` (L1): post-bootstrap environment validation
- `onboard` (L2): developer onboarding verification
- User: `/rune env-check` direct invocation

## Execution

### Step 1: Detect Project Type

Read project configuration files to determine what environment is needed:

1. Use `Glob` to check for project config files:
   - `package.json` → Node.js project
   - `pyproject.toml` / `setup.py` / `requirements.txt` → Python project
   - `Cargo.toml` → Rust project
   - `go.mod` → Go project
   - `Gemfile` → Ruby project
   - `docker-compose.yml` / `Dockerfile` → Docker project
   - `.nvmrc` / `.node-version` → specific Node version required
   - `.python-version` → specific Python version required

2. Read each detected config file to extract version constraints:
   - `package.json` → `engines.node`, `engines.npm`, dependency versions
   - `pyproject.toml` → `requires-python`, dependency versions
   - `Cargo.toml` → `rust-version`
   - `go.mod` → `go` directive version

3. Build an environment requirements checklist from the detected configs.

### Step 2: Runtime Version Check

For each detected runtime, verify the installed version matches constraints:

```bash
# Node.js
node --version    # Compare against package.json engines.node or .nvmrc
npm --version     # Compare against package.json engines.npm
# or pnpm/yarn/bun depending on lockfile present

# Python
python --version  # Compare against pyproject.toml requires-python
pip --version

# Rust
rustc --version   # Compare against Cargo.toml rust-version
cargo --version

# Go
go version        # Compare against go.mod go directive

# Docker
docker --version
docker compose version
```

**Version comparison logic:**
- If the constraint is `>=18.0.0` and installed is `20.11.1` → PASS
- If the constraint is `>=18.0.0` and installed is `16.20.2` → BLOCK (wrong major version)
- If the runtime is not installed at all → BLOCK
- If no version constraint exists in config → WARN (version unconstrained)

### Step 3: Required Tools Check

Detect and verify tools the project depends on:

1. **Package manager**: Check which lockfile exists and verify the matching tool is installed
   - `package-lock.json` → npm
   - `pnpm-lock.yaml` → pnpm
   - `yarn.lock` → yarn
   - `bun.lockb` → bun
   - `poetry.lock` → poetry
   - `uv.lock` → uv
   - Mismatched lockfile + installed tool → WARN (e.g., yarn.lock exists but only npm installed)

2. **Git**: `git --version` — required for all projects
3. **Docker**: Check only if `Dockerfile` or `docker-compose.yml` exists
4. **Database tools**: Check if `prisma`, `drizzle`, `alembic`, `django` migrations exist → verify DB client installed
5. **Build tools**: Check for `turbo.json` (turborepo), `nx.json` (Nx), `Makefile`, etc.

6. **Hard dependencies** — tools the project WRAPS (not just uses as dev dependency):
   Scan for evidence that the project wraps an external tool:
   - `Grep` for `shutil.which(`, `which `, `command -v ` → project looks up an executable at runtime
   - `Grep` for `subprocess.run(`, `child_process.exec(`, `Deno.Command(` → project invokes external CLI
   - `Read` README/docs for "requires X installed" or "depends on X"

   For each detected hard dependency, apply the **9-tier binary detection** below — checking only `which`/`where` is insufficient and produces the largest category of "works on my machine" false-negatives (user has binary installed but PATH is stale, or installed via a package manager that didn't register it, or installed as a desktop app with a bundled binary).

   **9-Tier Binary Detection** (stop at first hit):

   | Tier | Source | Catches |
   |------|--------|---------|
   | 1 | Explicit `---bin ` flag | CI, automation, manual override |
   | 2 | Skill-specific env var `__BIN` | Per-project pinning |
   | 3 | Tool-family env var `_APP_BIN` | Ecosystem conventions |
   | 4 | Generic tool env var `_BIN` | Legacy overrides |
   | 5 | Platform desktop-app bundle (macOS `.app/Contents/Resources`, Windows `%LOCALAPPDATA%\Programs`, Linux `/opt`) | Desktop app users (~40% of population) |
   | 6 | PATH lookup (`which`/`where.exe`) | Standard shell users |
   | 7 | Package manager global bin (`npm config get prefix`, `pnpm`, `pipx --list`, `cargo install --root`) | npm-global on Windows (PATH oversight) |
   | 8 | Platform common directories — Unix: `~/.local/bin`, `~/.npm-global/bin`, `~/.bun/bin`, `~/.cargo/bin`, `~/.deno/bin`, `~/.volta/bin`, `~/.asdf/shims`, `~/.proto/bin`, `/opt/homebrew/bin`, `/usr/local/bin`. Windows: `%APPDATA%\npm`, `%USERPROFILE%\.bun\bin`, `%USERPROFILE%\.cargo\bin`, `%USERPROFILE%\.deno\bin`, `%LOCALAPPDATA%\Microsoft\WindowsApps`, `%ProgramFiles%\nodejs` | Bun / Cargo / Deno / Volta / asdf / proto users + manual installers |
   | 9 | Platform release archive names (e.g., `codex-x86_64-unknown-linux-musl`, `-aarch64-apple-darwin`) | Release-tarball downloaders |

   **Verdict:**
   - Tool found via any tier → PASS (log which tier + version)
   - Tool NOT found → **BLOCK** with per-OS install guidance:
     ```
     [ENV-XXX] Required tool '' not found (9-tier lookup exhausted)
       → Debian/Ubuntu: sudo apt install 
       → macOS: brew install  (or desktop app: )
       → Windows: winget install  (or choco install )
       → Any platform: npm install -g  (if Node tool)
       → Manual: 
       → Pin explicitly: export _BIN=/path/to/binary
     ```
   - This prevents the entire class of "it worked in CI but not locally" failures where `subprocess.run()` silently fails
   - Reference implementation: `scripts/codex_imagen_bridge.mjs` in `@rune-pro/media` ports this pattern

### Step 4: Port Availability Check

Detect which ports the project needs and check if they're available:

1. Parse port information from:
   - `package.json` scripts (look for `--port`, `-p`, `PORT=` patterns)
   - `.env` / `.env.example` (look for `PORT=`, `DATABASE_URL` with port)
   - `docker-compose.yml` (ports section)
   - Common defaults: 3000 (Next.js/React), 5173 (Vite), 8000 (Django/FastAPI), 5432 (PostgreSQL), 6379 (Redis)

2. Check each port:
   ```bash
   # Cross-platform port check
   # Windows: netstat -ano | findstr :PORT
   # Unix: lsof -i :PORT or ss -tlnp | grep :PORT
   ```

3. If port is in use → WARN with the process name using it

### Step 5: Environment Variables Check

Compare required env vars against actual configuration:

1. Read `.env.example` or `.env.template` if it exists
2. Read `.env` if it exists (DO NOT log values — only check key presence)
3. For each key in `.env.example`:
   - Present in `.env` → PASS
   - Missing from `.env` → WARN (with the key name, never the expected value)
4. Check for dangerous patterns:
   - `.env` committed to git (check `.gitignore`) → BLOCK (security risk)
   - Placeholder values still present (`your-api-key-here`, `changeme`, `xxx`) → WARN

### Step 6: Disk Space and System Resources

Quick system health check:

1. **Disk space**: Check available space on the project drive
   - =18.0.0 required
  → Fix: `nvm install 18 && nvm use 18`

### WARNINGS
- [ENV-002] Port 3000 in use by process "node" (PID 12345)
  → Fix: `kill 12345` or change PORT in .env
- [ENV-003] Missing env var: DATABASE_URL (required by .env.example)
  → Fix: Copy from .env.example and fill in your database connection string

### PASSED
- [ENV-004] pnpm 9.1.0 ✓ (matches pnpm-lock.yaml)
- [ENV-005] Git 2.44.0 ✓
- [ENV-006] Docker 25.0.3 ✓
- [ENV-007] Disk space: 42 GB available ✓
```

## Constraints

1. MUST be read-only — never install, update, or modify anything on the developer's machine
2. MUST NOT log environment variable VALUES — only check key presence (security)
3. MUST provide copy-paste remediation commands for every BLOCK and WARN finding
4. MUST handle cross-platform differences (Windows/macOS/Linux) gracefully
5. MUST complete in under 10 seconds — use parallel Bash calls where possible
6. MUST NOT block on WARN findings — only BLOCK findings prevent proceeding

## Sharp Edges

| Failure Mode | Severity | Mitigation |
|---|---|---|
| False BLOCK on version — semver parsing error | HIGH | Use simple major.minor comparison, not full semver regex |
| Slowness on Windows — netstat/port checks are slower | MEDIUM | Timeout port checks at 3s, skip if slow |
| .env file contains secrets — accidentally logged | CRITICAL | NEVER read .env values, only check key existence via grep for key names |
| Platform detection wrong — WSL vs native Windows | MEDIUM | Check for WSL explicitly (`uname -r` contains "microsoft") |
| Over-checking — flagging optional tools as required | MEDIUM | Only check tools evidenced by config files, not speculative |
| Missing hard dependency — project wraps external CLI but tool not checked | HIGH | Step 3.6: scan for `shutil.which`, `subprocess.run`, `child_process.exec` → verify tool exists on PATH |
| Hard dep found but wrong version — tool exists but API changed | MEDIUM | Log version for manual review. Version compatibility is project-specific — don't guess |

## Done When

- All detected project runtimes version-checked against constraints
- Package manager matches lockfile type
- Required ports checked for availability
- Environment variables compared against .env.example (keys only)
- Disk space verified adequate
- Structured report with READY / READY WITH WARNINGS / BLOCKED verdict
- Every BLOCK/WARN finding has a copy-paste remediation command

## Cost Profile

~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.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [Rune-kit](https://github.com/Rune-kit)
- **Source:** [Rune-kit/rune](https://github.com/Rune-kit/rune)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** yes
- **Shell / process execution:** yes
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: flagged — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-rune-kit-rune-sentinel-env
- Seller: https://agentstack.voostack.com/s/rune-kit
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
