# TASK: harness fleet unlocks — turn pool (529) + Redmine-claim dispatch (530) ## Context Repo ~/projects/meta/MOPAC/harness (main @ a3d312c). The loop's own turns round-limit on these features (4 attempts, zero commits) — you are the dedicated lane; the loop is parked off harness-core. Everything else queued tonight depends on these two. ## Existing work to salvage - reports/REPORT-demo-529-20260829-211035.md + REPORT-demo-528-20260829-212502.md contain exploration findings (read them first for the map: conductor, daemon, intake, writeback packages). - internal/writeback has retry/verify/park (landed, green) — reuse its patterns for claim release. ## Part 1 — 529 turn pool (commit BEFORE starting Part 2) 1. `[loop] max_concurrent_turns` (default 1; fleet uses 2-3) — bounded worker pool (goroutines + channel semaphore). 2. Per-repo mutex: one turn per work repo at a time; different repos parallel. Repo derived from ticket category/prefix mapping in config (`[loop.repo_map]` category->path, default harness root). 3. status.json: active turns + pending count per scan. 4. Tests: pool bound respected, per-repo serialization, cross-repo parallelism (fake clock or short sleeps OK). ## Part 2 — 530 Redmine-claim dispatch 1. On dispatch: PUT status In Progress + note "claimed by @" BEFORE the turn; claim race lost -> skip to next candidate. 2. Success -> Resolved (existing map); failure/timeout/park -> back to New + note. 3. Stale-claim release: claim older than 2x turn_timeout_secs with no report -> New. 4. Tests: two-loop race exactly-one-wins; stale release; claim failure skips candidate. ## Discipline (hard) - ./dev.sh check green before EACH commit (bash cap 60s: run package-scoped tests `./dev.sh test ./internal/loop/...` then full check before the final commit). - COMMIT INCREMENTALLY: Part 1 in >=2 commits, Part 2 in >=2 commits. Push after each part. - No new deps. No broad pkill. Exit 0 only if pushed + full check green. ## Deliverable REPORT-20260829-1800-fleet-unlocks.md to ~/.coordinate/inbox-pmo/: commit list, test counts, config knobs, smoke evidence (run loop briefly with max_concurrent_turns=2 against the fake if feasible). NO Redmine writes.