feat(pool): add start_index so manual and auto pools can coexist

Production had two disjoint tmux pools named alike but for different
purposes:
  ccl-0..ccl-9           — manual/interactive sessions (operator)
  ccl-auto-11..ccl-auto-20 — autonomous dispatcher pool

Until now the daemon's loops iterated prefix + 0..Max, so with the
deployed config ("prefix: ccl-auto", min=2, max=10) the dispatcher
looked for sessions "ccl-auto0..ccl-auto9" that never existed, while
the real auto pool ccl-auto-11..20 was invisible. Net effect: no task
was ever dispatched, and killAllPoolSessions fabricated phantom
"ccl-auto0/1" sessions on each swap.

- AutonomousConfig gains StartIndex (yaml start_index, default 0).
  Behaviour is unchanged when StartIndex is 0.
- Monitor, switcher (kill + recreate), dispatcher (findFreeSession),
  and lifecycle (EnsureAll + reconcile) all iterate
  [StartIndex, StartIndex+Max) so the daemon only touches its own
  range and leaves ccl-0..ccl-9 alone.
- Production config updated to prefix: "ccl-auto-", start_index: 11,
  min: 10, max: 10 — covering the 10 real ccl-auto-11..20 sessions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ubuntu 2026-04-15 20:39:57 +00:00
parent 8fdb1937fc
commit eb6b74c547
6 changed files with 73 additions and 14 deletions

View file

@ -61,12 +61,13 @@ func (m *Manager) EnsureAllSessions() {
}
}
// Ensure autonomous pool sessions (prefix + index).
// Ensure autonomous pool sessions (prefix + index, starting at StartIndex).
prefix := m.config.Pool.Autonomous.Prefix
if prefix == "" {
prefix = "ccl-auto-"
}
for i := 0; i < m.config.Pool.Autonomous.Min; i++ {
start := m.config.Pool.Autonomous.StartIndex
for i := start; i < start+m.config.Pool.Autonomous.Min; i++ {
name := sessionName(prefix, i)
if !m.tmux.HasSession(name) {
if err := m.tmux.CreateSession(name, ""); err != nil {
@ -86,12 +87,13 @@ func (m *Manager) reconcile() {
m.reconcileSession(ds.Name, ds.Project)
}
// Reconcile the autonomous pool (min sessions).
// Reconcile the autonomous pool (min sessions, starting at StartIndex).
prefix := m.config.Pool.Autonomous.Prefix
if prefix == "" {
prefix = "ccl-auto-"
}
for i := 0; i < m.config.Pool.Autonomous.Min; i++ {
start := m.config.Pool.Autonomous.StartIndex
for i := start; i < start+m.config.Pool.Autonomous.Min; i++ {
name := sessionName(prefix, i)
m.reconcileSession(name, "")
}