Add a channel-based semaphore (SPINDLE_SERVER_MAX_CONCURRENT_WORKFLOWS, default 8) that blocks workflow goroutines from starting a container until a slot is free. Each workflow acquires a slot before SetupWorkflow and releases it on exit via defer.
Combined with the 6 GiB per-container limit (MAX_JOB_MEMORY_MB), this bounds total container memory to ~48 GiB on the current 64 GiB host. MAX_JOB_COUNT still controls pipeline-level concurrency at the queue. Without this semaphore, max workflows were effectively unbounded and (wrongly) assumed to be capped at MAX_JOB_COUNT.
Signed-off-by: Anirudh Oppiliappan anirudh@tangled.org