Skip to content
Back to skills

Stack Health

CSecurity

Full stack-integrity health check for a self-hosted Claude Code harness box (reference deployment: Oracle Cloud A1, aarch64) — verifies every systemd service, any configured extra service (HARNESS_EXTRA_SERVICES, e.g. a Discord bot gateway) and its Node engine compliance, listening ports, local endpoints, external HTTPS + TLS cert expiry for your configured vhosts, toolchain/PATH integrity, MCP server resolvability, claude-mem capture, host resources, and pending updates. Use when the user as...

  • 2 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 26, 2026
ai-agentsgoshellbashnodegit

Works with

  • claude code
  • cli
  • mcp

Security analysis

C67/100
  • criticalAccesses sensitive system or user directories
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 2 files and shows the line behind each finding

Scanned September 26, 2026

npx -y skills add alhe99/mows-harness --skill stack-health --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Stack Health?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Stack Health
[![Security: C — Skills Directory](https://www.skillsdirectory.com/api/skills/alhe99-stack-health/badge)](https://www.skillsdirectory.com/skills/alhe99-stack-health)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: stack-health
description: "Full stack-integrity health check for a self-hosted Claude Code harness box (reference deployment: Oracle Cloud A1, aarch64) — verifies every systemd service, any configured extra service (HARNESS_EXTRA_SERVICES, e.g. a Discord bot gateway) and its Node engine compliance, listening ports, local endpoints, external HTTPS + TLS cert expiry for your configured vhosts, toolchain/PATH integrity, MCP server resolvability, claude-mem capture, host resources, and pending updates. Use when the user asks whether the VM or stack is healthy, whether services are up, whether the site or Discord bots are working, after a reboot or upgrade, or asks to check on the server. For billing/free-tier questions use oci-free-check instead."
---

# stack health

Run the script. It's deterministic — don't re-derive the checks by hand.

```bash
~/.claude/skills/stack-health/check.py
```

Takes ~60s. Runs **from this machine**, not on the box, so the HTTPS/TLS checks
come from a genuinely external vantage point while host checks go over one
multiplexed SSH connection.

Configure it for your deployment via environment variables:

| Variable | Purpose | Default |
|----------|---------|---------|
| `HARNESS_SSH_HOST` | SSH alias for the box (define it in `~/.ssh/config`) | `harness` |
| `HARNESS_DOMAIN` | Primary vhost to check over HTTPS/TLS | `example.com` |
| `HARNESS_SUBDOMAINS` | Comma-separated subdomains, checked as `<sub>.<HARNESS_DOMAIN>` | (none) |
| `HARNESS_EXTRA_SERVICES` | Extra services to check, `name:port,name2:port2` — each gets a root systemd --user unit check (section 2), a listening-port check (section 3), and a local-endpoint check (section 4) | (none — section 2 skipped entirely) |
| `HARNESS_DISCORD_BOTS` | Comma-separated bot instance names to look for in an extra service's logs | (none — sub-check skipped) |
| `HARNESS_USER` | Unprivileged account running claude-mem, for the claude-mem check | (none — sub-check skipped) |

## Exit codes

| Code | Meaning | What to do |
|------|---------|------------|
| `0` | All healthy | Report briefly. Don't paste every green tick. |
| `1` | Healthy with warnings | Read each one. Often advisory (apt updates, reboot pending, a bot quiet in logs). |
| `2` | **Something is down or broken** | Lead with it, name the service, and offer the fix. |

## What it covers

1. **systemd services** — 12 units + any failed unit on the box
2. **extra services** (optional, `HARNESS_EXTRA_SERVICES`, skipped entirely if unset) —
   root *user* service state, linger (must survive reboot), version,
   **node engine compliance**, configured Discord bots (`HARNESS_DISCORD_BOTS`), error count
3. **Ports** — 7 required + any configured extra services; `:37777` is advisory (session-spawned, absent is normal)
4. **Local endpoints** — with per-port expected codes (`:4180` 302 and `:7681` 404-on-`/`
   are both *correct*, not faults)
5. **External HTTPS** — your configured vhosts (`HARNESS_DOMAIN` + `HARNESS_SUBDOMAINS`) +
   TLS expiry, warns under 14 days (Caddy renews at 30)
6. **Toolchain integrity** — PATH resolution and MCP resolvability
7. **claude-mem** — health verdict + DB write freshness
8. **Host** — memory (incl. the 20% idle-reclamation bar), disk, load, kernel,
   reboot-pending, apt

## Scope

Stack integrity only. **Billing and free-tier limits live in `oci-free-check`** —
don't duplicate that here. The one overlap is memory %, because it doubles as the
idle-reclamation signal.

## Gotchas encoded — do not "simplify" these out

Each caused a wrong answer when this was built:

- **`env PATH=... command -v x` is broken.** `command` is a shell *builtin*, so
  `env` tries to exec a binary named "command" and fails — making every probe
  report MISSING. The script exports PATH and uses the builtin directly. The first
  version of this check reported 7 false failures on a perfectly healthy box.
- **Parse `Environment=PATH=` with `sed -n 's/^Environment=PATH=//p'`, not
  `cut -d= -f2-`.** `cut` leaves a literal `PATH=` prefix, so the first directory
  becomes the invalid path `PATH=/home/<user>/.local/bin` and gets skipped —
  silently changing which binary appears to win.
- **A registered MCP server whose command doesn't resolve is a real failure.**
  That is exactly how codegraph broke after migration: `.claude.json` still had the
  registration, but the binary was gone.
- **fnm-scoped npm globals are a migration blind spot.** Packages installed with
  `npm i -g` while an *fnm* node was active live under `.local/share/fnm/...`, which
  is excluded as x86 during any arch migration. codegraph was lost this way.
- **Third-party apt repos are the other blind spot.** `gh` comes from
  cli.github.com, not Ubuntu main, so a base-package install misses it. Its absence
  is especially nasty: `.gitconfig` hardcodes
  `!/usr/bin/gh auth git-credential`, so git reports an *auth* failure rather than a
  missing binary, and `git status` still looks clean because it compares against a
  stale `origin/*` ref. This went unnoticed for **19 days**. Hence the explicit
  credential-helper check — verify the helper binary exists AND `gh auth status`
  passes, never just that git is installed.
- If a CLI goes missing, suspect those two categories first.
- **An extra service's node engine must be checked, not assumed.** One such
  service once required `>=22.22.3` while its tree sat under node v22.22.1, and
  worked only because `/usr/bin` happened to precede the nvm path in the unit's
  PATH. Correct by luck is not correct.
- **`:7681` serves under `--base-path /term`**, so `/` returning 404 is right.
  Probe `/term/`.

## Reporting

Lead with the verdict. On exit 0 keep it to a couple of lines. On exit 2, name what
is down and what it affects (e.g. caddy down = all six hostnames offline; a
configured extra service down = whatever depends on it, e.g. its Discord bots,
offline), then offer the fix.

Files in this skill

  • SKILL.md5.8 KB
  • check.py20.5 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.