fix: enforce worker spawn concurrency cap#108
Conversation
bfffe1b to
120ed2e
Compare
|
Final status: implementation is merge-ready by local gates, remote CI, and final-review pass. Review cycles:
Current gates:
Parked for human merge because the PR touches sensitive path |
|
Superseded: #96 was fixed and merged via #102 (client-side empty-harness approach, reviewed + CI-green). This v2 (server-side) is redundant and touches sensitive session_manager/**. Closing to avoid a conflicting double-implementation. If we want to migrate to the server-side resolution, file a fresh issue. |
|
Current status update (2026-07-07): keeping this PR parked as the merge-ready candidate for the #96 scope-add requested in issue comments and the current session request. This supersedes my earlier "superseded" comment on this PR thread. Verified again on head
Do not automerge: this touches sensitive path |
polymath-orchestrator
left a comment
There was a problem hiding this comment.
INDEPENDENT REVIEW — PR #108, cycle 2
Reviewer: Claude
Head SHA: 4c9cf0f
Previous findings status:
- resolved — observer.go now distinguishes a WORKER_CONCURRENCY_CAP spawn error and defers remaining intake work without triggering failure backoff. The new regression test covers the mid-pass cap collision and verifies the next poll is not suppressed.
Buckets reviewed: bugs, architecture, security, performance, repo-specific-invariants, tests, spec-drift, bypass-flags, docs
Verdict: approved
Findings: Zero findings.
Summary:
- Bugs: no remaining off-by-one, nil, race, lock leak, or error-path defect found in the manager admission path or intake cap handling.
- Architecture/integration: cap and worker-mix admission now converge on daemon-side state; the global spawn mutex is coarse but acceptable for this correctness fix.
- Security: no new external input, authz, secret, deserialization, or shell-injection surface.
- Performance: no unbounded loops or N+1 behavior; the manager cap check is a race backstop, not the common intake path.
- Repo-specific invariants: sensitive path backend/internal/session_manager/** is touched, so this remains parked for human merge.
- Tests: regression coverage now includes manager in-flight seed rows and intake mid-pass cap collision; backend build/vet/test/lint passed locally.
- Spec drift: no OpenSpec change applies; CLI help and config comments now match shared-cap semantics.
- Bypass flags: none found.
- Docs: no stale intake-only maxConcurrent wording found.
|
final-review: clean — reviewer=claude, head=4c9cf0f356e9b608f020080803ed6bdbab6d44c1 Verdict artifact: #108 (review) Status: local gates passed, remote CI passed, review-passed status is green, and current-head review threads are clear. Parked for human merge because this PR touches sensitive path |
4c9cf0f to
7ea545c
Compare
|
Final-review (independent, claude/fable): CLEAN. Per-project worker concurrency cap enforced server-side ( |
Summary
trackerIntake.maxConcurrenta project-wide live worker cap shared by intake and manual spawns, while keeping worker-mix selection server-side from the already-merged P0: ao spawn resolves harness to project default, bypassing the weighted mix (only intake gets it) #96 fix.WORKER_CONCURRENCY_CAP409 responses and update CLI/config wording.Test plan
go test ./internal/session_manager -run TestSpawn_RejectsWorkerWhenProjectAtConcurrencyCap -count=1failed before implementation with missing cap sentinel.go test ./internal/session_manager -run 'TestSpawn_RejectsWorkerWhenProjectAtConcurrencyCap|TestSpawn_CountsInFlightSeedRowsAgainstConcurrencyCap|TestSpawn_WorkerMix' -count=1go test ./internal/observe/trackerintake -run 'TestPollHonorsMaxConcurrentAgainstLiveWorkers|TestPollDefersWhenAlreadyAtMaxConcurrent|TestLiveWorkersByProjectIgnoresTerminatedAndNonWorkers|TestPollWorkerMixRespectsConcurrencyCap' -count=1go test ./internal/service/session -run TestToAPIError -count=1cd backend && go build ./...cd backend && go vet ./...cd backend && go test ./...cd backend && go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@v2.12.2 run --path-mode=absReview notes
Merge note
Sensitive paths touched:
backend/internal/session_manager/**. Per repo policy, do not automerge; park for human review/merge.