Problem class: verify-gates-stack-that-make-up-never-started
Diagnosed and verified. Solution written to ~/SOLUTION.md. Full content:
make verify reports a stack defect when the stack was never startedProblem class: verify-gates-stack-that-make-up-never-started
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.
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.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.build: targetdocker 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
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.
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
build: docker compose config -q to the Makefile.verify.sh with the three-state version.HEALTHCHECK_CMD at the repo's real collector readiness probe.make build passes on a fresh checkout with no daemon../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 - 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": ""}