Skip to content
Back to skills

Verify System

BSecurity

End-to-end system health verification. Checks all containers, ports, endpoints, and pipelines (logging, email, auth, socket, worker). Proves the system is truly working, not just running.

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 12, 2026
databasesgobashsqlnodedockerapi

Works with

  • cli
  • api

Security analysis

B84/100
  • mediumUses curl or wget to download content
  • criticalExfiltrates credentials via HTTP — exact pattern from Snyk ToxicSkills study

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

Scanned September 12, 2026

npx -y skills add aibot88/sec_skill_store --skill verify-system --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Verify System?

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

Security grade badge for Verify System
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/aibot88-verify-system/badge)](https://www.skillsdirectory.com/skills/aibot88-verify-system)

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: verify-system
description: "End-to-end system health verification. Checks all containers, ports, endpoints, and pipelines (logging, email, auth, socket, worker). Proves the system is truly working, not just running."
argument-hint: ""
---

# /verify-system Skill

## Purpose

Proves that the entire system is **truly working** — not just "containers are up" but every pipeline, every connection, every integration is functional. Run after `/create-new-project` or anytime you need confidence that the system is healthy.

**Philosophy:** Don't say "it's ready" — prove it with evidence.

## Verification Levels

### Level 0: Configuration Sanity

Static checks against `docker-compose.yml` — catch blueprint drift before paying the cost of `docker compose up`. These verify that what infra-agent generated matches what `infra-agent/children/` documents.

#### 0.1 Health-gated dependencies

Every service that talks to a stateful infrastructure dependency (PostgreSQL, RabbitMQ, Redis, Elasticsearch) must wait on `service_healthy`, not `service_started`. `service_started` only proves the container's PID 1 exists — the broker/db may still be in its bootstrap loop, causing first-run connection errors that "auto-recover" but pollute logs and confuse new contributors.

```bash
# Find any depends_on blocks that target stateful services with service_started
grep -nE "(rabbitmq|postgres|db|redis|elasticsearch):\s*$" -A1 docker-compose.yml \
  | grep -B1 "condition: service_started"
```

**Pass:** No matches — every stateful dep uses `service_healthy`.
**Fail diagnostic:** Print the offending service+dependency pairs and recommend flipping to `service_healthy`. See [infra-agent/children/health-checks.md](../../agents/infra-agent/children/health-checks.md) for the canonical pattern.

#### 0.2 Shared .NET project shadow volumes

When the API/Worker/Socket/LogIngest services mount source from host, every referenced .NET project (`Domain`, `Application`, `Infrastructure`, `Logging`, plus any other `.csproj` referenced by a service) needs its `bin/` and `obj/` shadowed by named volumes. Otherwise host-side `dotnet build` (run by a developer on macOS) collides with container-side Linux artefacts and produces mysterious assembly-load failures.

```bash
# For each shared project under src/, both bin and obj volumes must exist
for proj in Domain Application Infrastructure Logging; do
  base=$(echo "$proj" | tr '[:upper:]' '[:lower:]')   # domain, application, infrastructure, logging
  short=${base%ation}                                  # application → applic; tweak as needed per project
  grep -qE "^\s*${base}_bin:|^\s*${short}_bin:" docker-compose.yml || echo "MISSING: ${base}_bin"
  grep -qE "^\s*${base}_obj:|^\s*${short}_obj:" docker-compose.yml || echo "MISSING: ${base}_obj"
done
```

(Exact short-name convention follows [infra-agent/children/volume-strategy.md](../../agents/infra-agent/children/volume-strategy.md): `domain_bin`, `app_bin`, `infra_bin`, `logging_bin` and their `_obj` siblings. Any project referenced by a `.csproj` ProjectReference inside a service must appear in that service's `volumes:` block AND in the top-level `volumes:` declaration.)

**Pass:** Every shared project has a `_bin` and `_obj` named volume, declared at the top level AND mounted into every service whose csproj references it.
**Fail diagnostic:** List the missing volumes and the affected services. See [infra-agent/children/volume-strategy.md](../../agents/infra-agent/children/volume-strategy.md) — "Type 1: Shadow Volumes".

**Report format:**
```
Level 0 — Configuration:
  ✅ Health-gated deps      All stateful depends_on use service_healthy
  ✅ Shadow volumes         domain/app/infra/logging bin+obj all declared and mounted
  Result: ✅ PASS (2/2 checks)
```

If Level 0 fails, **stop and fix the compose file** before running Level 1+ — runtime checks against a structurally drifted compose file produce noisy false-positives.

### Level 1: Containers Running

Check every container is up and healthy (not just "created" or "restarting"):

```bash
docker compose ps --format "table {{.Name}}\t{{.Status}}"
```

**Pass criteria:**
- All containers show "Up" status
- Health-checked services show "(healthy)"
- No container in "Restarting" or "Exited" state (except init containers like minio-init which are expected to exit)

**Report format:**
```
Level 1 — Containers:
  ✅ wfm-api          Up 2 minutes
  ✅ wfm-db           Up 2 minutes (healthy)
  ✅ wfm-rabbitmq     Up 2 minutes (healthy)
  ✅ wfm-redis        Up 2 minutes (healthy)
  ✅ wfm-elasticsearch Up 2 minutes (healthy)
  ⚪ wfm-minio-init   Exited (expected — one-shot init)
  ... (all containers)
  Result: ✅ PASS (14/14 running)
```

### Level 2: Ports Accessible

For every service with an exposed port, verify TCP connectivity:

```bash
curl -sf -o /dev/null -w "%{http_code}" http://localhost:{port}/
```

**Services to check:**

| Service | Port | Check Method |
|---------|------|-------------|
| API | {api_port} | HTTP GET /api/health/ping |
| Swagger | {api_port} | HTTP GET /swagger/index.html |
| Socket | {socket_port} | HTTP GET (SignalR negotiate) |
| PostgreSQL | {db_port} | docker compose exec db pg_isready |
| RabbitMQ Management | {rmq_mgmt_port} | HTTP GET / |
| Redis | {redis_port} | docker compose exec redis redis-cli ping |
| Elasticsearch | {es_port} | HTTP GET /_cluster/health |
| Kibana | {kibana_port} | HTTP GET /api/status |
| Mailpit | {mailpit_port} | HTTP GET / |
| MinIO Console | {minio_console_port} | HTTP GET / |
| Adminer | {adminer_port} | HTTP GET / |
| Redis Commander | {redis_ui_port} | HTTP GET / |

**Report format:**
```
Level 2 — Ports:
  ✅ API (13000)           HTTP 200
  ✅ Swagger (13000)       HTTP 200
  ✅ PostgreSQL (15432)    pg_isready OK
  ✅ RabbitMQ (25673)      HTTP 200
  ✅ Redis (16379)         PONG
  ✅ Elasticsearch (19200) green
  ✅ Kibana (15601)        HTTP 200
  ✅ Mailpit (18025)       HTTP 200
  ✅ MinIO (19001)         HTTP 200
  ✅ Adminer (18083)       HTTP 200
  ✅ Redis Commander (18082) HTTP 200
  Result: ✅ PASS (12/12 accessible)
```

### Level 3: Application Health

Beyond port accessibility — does the application return **meaningful responses**?

```bash
# API health
curl -sf http://localhost:{api_port}/api/health/ping
# Expected: {"message":"pong","timestamp":"..."}

# Elasticsearch cluster
curl -sf http://localhost:{es_port}/_cluster/health
# Expected: {"status":"green"} or {"status":"yellow"}

# RabbitMQ queues exist
curl -sf -u guest:guest http://localhost:{rmq_mgmt_port}/api/queues
# Expected: logs.elasticsearch and emails.smtp queues listed

# Redis connectivity
docker compose exec redis redis-cli INFO server | head -5
# Expected: redis_version, uptime_in_seconds

# PostgreSQL tables
docker compose exec db psql -U {user} -d {db} -c '\dt'
# Expected: migration history table + any seeded tables
```

**Report format:**
```
Level 3 — Application Health:
  ✅ API health           {"message":"pong"}
  ✅ Elasticsearch        cluster: green, nodes: 1
  ✅ RabbitMQ queues      logs.elasticsearch ✓, emails.smtp ✓
  ✅ Redis                v7.x, uptime: 120s
  ✅ PostgreSQL           tables: __EFMigrationsHistory, Users, AuditLogs
  ✅ Seed data            admin@test.com exists
  Result: ✅ PASS (6/6 healthy)
```

### Level 4: Pipeline Smoke Tests

The most important level. **End-to-end proof** that each pipeline works.

#### 4.1 Logging Pipeline

```
Test: API writes a log → RMQ → LogIngest → Elasticsearch

Steps:
1. Call API endpoint: GET /api/health/ping
2. Wait 5 seconds (batch flush)
3. Query Elasticsearch for the log:
   curl -sf http://localhost:{es_port}/{project}-logs-*/_search?q=ping
4. Verify: log entry exists with service:"api", message contains "ping"
```

**Pass:** Log entry found in Elasticsearch within 10 seconds of API call.

#### 4.2 Email Pipeline

```
Test: API triggers email → RMQ → MailSender → Mailpit

Steps:
1. Call API auth register endpoint (if available) or trigger a test email
   POST /api/auth/register { email: "test-verify@test.com", password: "Test1234!" }
   (This should trigger a welcome email)
2. Wait 5 seconds
3. Check Mailpit for the email:
   curl -sf http://localhost:{mailpit_port}/api/v1/messages
4. Verify: email to test-verify@test.com exists in Mailpit
```

**Pass:** Email visible in Mailpit. If no auth register endpoint yet, skip with note: "Email pipeline ready but no trigger endpoint available yet."

#### 4.3 Auth Pipeline

```
Test: Register → Login → Token → Protected endpoint

Steps:
1. Register: POST /api/auth/register { email, password }
   → Expected: 200 + accessToken + refreshToken
2. Login: POST /api/auth/login { email, password }
   → Expected: 200 + accessToken
3. Use token: GET /api/health/ping with Authorization: Bearer {token}
   → Expected: 200
4. Without token: GET /api/auth/me (if exists)
   → Expected: 401
```

**Pass:** Full auth cycle works. If auth endpoints not yet implemented, skip with note.

#### 4.4 Socket Pipeline

```
Test: Socket connects and API can broadcast

Steps:
1. Check Socket is accepting connections:
   curl -sf http://localhost:{socket_port}/health (if exists)
2. Check Socket logs for "connected to RabbitMQ" or startup messages
3. (Full WebSocket test requires a client — note as manual test)
```

**Pass:** Socket service running and RMQ connected.

#### 4.5 Worker Pipeline

```
Test: Worker job executes on schedule

Steps:
1. Check Worker logs for SampleJob execution:
   docker compose logs worker --tail 20 | grep "SampleJob"
2. Verify: at least one "SampleJob executing" log entry exists
3. If SampleJob calls API: verify the API received the call (check API logs)
```

**Pass:** SampleJob has executed at least once.

#### 4.6 Redis Integration

```
Test: Redis is being used (tokens, settings, etc.)

Steps:
1. Check Redis has keys:
   docker compose exec redis redis-cli DBSIZE
2. If auth exists: register a user, check refresh token in Redis:
   docker compose exec redis redis-cli KEYS "refresh_token:*"
```

**Pass:** Redis has entries (settings seed or tokens).

#### 4.7 MinIO/Storage (if enabled)

```
Test: Default bucket exists

Steps:
1. Check MinIO bucket:
   curl -sf http://localhost:{minio_api_port}/minio/health/ready
2. Or check via mc: docker compose exec minio mc ls local/
```

**Pass:** MinIO healthy and default bucket exists.

---

## Final Report

After all levels complete, produce a comprehensive report:

```
╔══════════════════════════════════════════════════════════════╗
║                    SYSTEM VERIFICATION                       ║
║                    {ProjectName} — {date}                    ║
╠══════════════════════════════════════════════════════════════╣
║                                                              ║
║  Level 0 — Configuration:  ✅ PASS  (2/2 static checks)     ║
║  Level 1 — Containers:     ✅ PASS  (14/14 running)         ║
║  Level 2 — Ports:          ✅ PASS  (12/12 accessible)      ║
║  Level 3 — App Health:     ✅ PASS  (6/6 healthy)           ║
║  Level 4 — Pipelines:                                        ║
║    4.1 Logging:            ✅ PASS  (API→RMQ→ES verified)   ║
║    4.2 Email:              ✅ PASS  (email in Mailpit)      ║
║    4.3 Auth:               ✅ PASS  (register→login→token)  ║
║    4.4 Socket:             ✅ PASS  (connected, RMQ linked) ║
║    4.5 Worker:             ✅ PASS  (SampleJob executed)    ║
║    4.6 Redis:              ✅ PASS  (keys present)          ║
║    4.7 Storage:            ✅ PASS  (MinIO ready, bucket OK)║
║                                                              ║
║  OVERALL: ✅ ALL SYSTEMS OPERATIONAL                         ║
║                                                              ║
║  The system is verified and ready for development.           ║
║                                                              ║
╠══════════════════════════════════════════════════════════════╣
║  Endpoints:                                                  ║
║    API:        http://localhost:13000                         ║
║    Swagger:    http://localhost:13000/swagger                 ║
║    Kibana:     http://localhost:15601                         ║
║    Mailpit:    http://localhost:18025                         ║
║    RabbitMQ:   http://localhost:25673                         ║
║    MinIO:      http://localhost:19001                         ║
║    Adminer:    http://localhost:18083                         ║
║    Redis UI:   http://localhost:18082                         ║
║                                                              ║
║  Test Credentials:                                           ║
║    Admin: admin@test.com / Admin123!                         ║
╚══════════════════════════════════════════════════════════════╝
```

If any test FAILS:
```
║  4.2 Email:              ❌ FAIL  (no email in Mailpit)     ║
║      → Check: docker compose logs mail-sender               ║
║      → Likely: RMQ topology not declared, or SMTP error     ║
```

Include diagnostic hints for each failure — what to check, what's likely wrong.

---

## Usage

**Standalone:**
```
/verify-system
```

**Called by /create-new-project:**
Phase 4 of project creation automatically runs this skill.

**After changes:**
Run anytime after infrastructure changes, compose updates, or if something feels wrong.

## Important Rules

1. **Wait for services to stabilize.** After `docker compose up`, wait 30-60 seconds before starting verification. Services need time to boot, migrate, connect.
2. **Skip gracefully.** If an endpoint doesn't exist yet (e.g., auth not implemented), skip that test with a note — don't fail the entire verification.
3. **Pipeline tests are the real proof.** Level 1-3 are basic checks. Level 4 proves the system actually works end-to-end.
4. **Log evidence.** For each pipeline test, show the actual log line or response that proves it worked.
5. **Ports from .env.** Read port numbers from `.env` file, don't hardcode. Every project might use different ports.
6. **Init containers are expected to exit.** minio-init, migration runners — these exit after their job. Don't flag them as failures.

## Accumulated Learnings

(Auto-rebuilt by /save-learnings from `learnings/*.md` frontmatter. Do not edit by hand. Initially empty — entries appear as the skill encounters reusable edge cases.)

Files in this skill

  • SKILL.md14.8 KB
  • source.json695 B

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.