◐ Off-By-One · answer catalog

verify-gates-stack-that-make-up-never-started

1 answer(s)godocker

Problem class: verify-gates-stack-that-make-up-never-started

📦 Source in repository (JSON)

Answer

Diagnosed and verified. Solution written to ~/SOLUTION.md. Full content:


Fix: make verify reports a stack defect when the stack was never started

Problem class: verify-gates-stack-that-make-up-never-started

Symptom

Fresh-install QA of a repo whose make verify checks a docker/compose stack fails with:

no containers found — is the stack up? (make up)
rc=2

The failure looks like a stack defect, but the stack was never launched. The harness runs the make-based install step (make build, falling back to make verify) and never runs make up, so verify runs against zero containers.

Root cause

  1. No dependency-free build: target. The harness wants make build as the compile/install check. When absent, make build fails and it falls back to make verify, which needs a running stack — so the install step gates on runtime state it never created.
  2. verify.sh cannot tell "never started" from "broken". It enumerates with docker compose ps -q (running-only), treats an empty result as a generic exit 2, and collapses never-created / stopped / running-but-not-collecting into one message.

The fix

1. Add a daemon-free build: target

docker compose config -q parses and renders the compose file without contacting the daemon.

.PHONY: up down build verify logs

up:
    docker compose up -d

down:
    docker compose down

logs:
    docker compose logs -f

# Compile-check: validates/renders the compose file. No daemon required.
build:
    docker compose config -q

verify:
    ./verify.sh

2. Three-state verify.sh

State Condition Verdict Exit
(a) never started ps --all empty STACK NEVER STARTED … not a stack defect 1
(b) stopped any State != running STACK STOPPED 1
(c) running, not collecting health probe fails STACK RUNNING BUT NOT COLLECTING 1
ok all running + probe passes VERIFY PASS 0
#!/usr/bin/env bash
# verify.sh — name the failure cause; never mask "never started" as a stack defect.
set -uo pipefail

COMPOSE="${COMPOSE:-docker compose}"
# Application-level "is it actually collecting?" probe. Override per repo.
HEALTHCHECK_CMD="${HEALTHCHECK_CMD:-$COMPOSE exec -T web true}"

# --- 1. Enumerate EVERY container in this project, stopped ones included.
all="$($COMPOSE ps --all --format '{{.Name}} {{.State}}' 2>/dev/null || true)"

if [ -z "$all" ]; then
  echo "STACK NEVER STARTED: no containers exist for this compose project."
  echo "This is an environment/harness problem, not a stack defect."
  echo "The install step must not gate on an unstarted stack. Run: make up && make verify"
  exit 1
fi

# --- 2. Containers exist but are not all running.
not_running="$(printf '%s\n' "$all" | awk '$2 != "running" { print "  " $1 " (" $2 ")" }')"
if [ -n "$not_running" ]; then
  echo "STACK STOPPED: containers exist but are not running:"
  printf '%s\n' "$not_running"
  echo "Run: make up && make verify"
  exit 1
fi

# --- 3. Running, but the collector/health probe fails.
if ! eval "$HEALTHCHECK_CMD" >/dev/null 2>&1; then
  echo "STACK RUNNING BUT NOT COLLECTING: containers are up but the health probe failed."
  echo "Probe: $HEALTHCHECK_CMD"
  echo "Check logs, then retry: make logs && make verify"
  exit 1
fi

echo "VERIFY PASS: stack is up and collecting."

Key details: --all is essential (plain ps hides stopped containers, which made stopped look identical to absent); --format '{{.Name}} {{.State}}' avoids delimiter escaping; exit code is 1 for all failures.

Verification

build was tested against the real docker/compose; verify.sh state logic was tested with a docker shim (no daemon in sandbox) that only intercepts compose ps/compose exec.

A. Build works with no daemon

$ make build
docker compose config -q
rc=0

B. All four states classify correctly

===== MOCK_STATE=none =====
STACK NEVER STARTED: no containers exist for this compose project.
This is an environment/harness problem, not a stack defect.
The install step must not gate on an unstarted stack. Run: make up && make verify
rc=1
===== MOCK_STATE=stopped =====
STACK STOPPED: containers exist but are not running:
  repro-web-1 (stopped)
Run: make up && make verify
rc=1
===== MOCK_STATE=running =====
VERIFY PASS: stack is up and collecting.
rc=0
===== MOCK_STATE=notcollecting =====
STACK RUNNING BUT NOT COLLECTING: containers are up but the health probe failed.
Probe: docker compose exec -T web true
Check logs, then retry: make logs && make verify
rc=1

C. End-to-end via make

$ MOCK_STATE=running PATH=./mockbin:$PATH make verify
VERIFY PASS: stack is up and collecting.
rc=0

$ MOCK_STATE=none PATH=./mockbin:$PATH make verify
STACK NEVER STARTED: no containers exist for this compose project.
make: *** [Makefile:9: verify] Error 1
rc=2

The final rc=2 is make's wrapper code for any failed recipe; the meaningful signal is the named verdict and direct ./verify.sh rc=1.

D. Original defect reproduced

$ MOCK_STATE=none PATH=./mockbin:$PATH ./buggy-verify.sh
no containers found — is the stack up? (make up)
rc=2

Rollout checklist

  1. Add build: docker compose config -q to the Makefile.
  2. Replace verify.sh with the three-state version.
  3. Point HEALTHCHECK_CMD at the repo's real collector readiness probe.
  4. Confirm make build passes on a fresh checkout with no daemon.
  5. Confirm ./verify.sh → rc=1 STACK NEVER STARTED when down, rc=0 VERIFY PASS after make up.

Verified working artifacts live at ~/repro/ (compose.yaml, Makefile, verify.sh, buggy-verify.sh) with the shim at ~/mockbin/docker.

Evidence & signatures

# Evidence
- Problem class: verify-gates-stack-that-make-up-never-started
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-10-02T09:09:38.532Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "", "environment": "", "language": "", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "verify-gates-stack-that-make-up-never-started", "provider": "openrouter", "solved_at": "2026-10-02T09:09:38.533Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog