Skip to content

fix: daemonize core-agent and clean up external-process agent#327

Closed
jrothrock wants to merge 4 commits into
masterfrom
fix/daemonize-core-agent
Closed

fix: daemonize core-agent and clean up external-process agent#327
jrothrock wants to merge 4 commits into
masterfrom
fix/daemonize-core-agent

Conversation

@jrothrock
Copy link
Copy Markdown
Collaborator

Summary

  • Daemonizes the core-agent process (--daemonize true, detached: true, proc.unref()) so it outlives any individual worker
  • Makes stopProcess() a no-op — workers must not kill the shared daemon
  • Drops allowShutdown config option (lifecycle is no longer worker-owned)
  • Bumps default core-agent version to v1.5.1
  • Removes unused imports and dead code in external-process.ts (TimeoutError, socketConnected, socketConnectionAttempts, getPoolStats(), stale comment, unused result variable)
  • Adds test verifying start() waits for the daemon on first call and resolves instantly on subsequent calls

Test plan

  • Run existing e2e test suite: npm test
  • Verify core-agent process survives worker restarts in a cluster setup
  • Confirm no double-spawn regression when multiple workers call setup() simultaneously

🤖 Generated with Claude Code

jrothrock and others added 4 commits May 29, 2026 16:39
The core-agent is now launched with --daemonize true so the binary
forks itself into a true daemon. No PID is retained by the worker.

Fixes two related cluster bugs:

1. Always-spawns bug: start() now returns early when peerRunning()
   is true instead of calling startProcess() unconditionally. Each
   worker that starts after the first simply connects to the already-
   running daemon.

2. Cluster-shutdown bug (issue #117): stopProcess() is now a no-op.
   Workers can no longer kill the shared core-agent when shutting
   down or crashing, which previously took down Scout for all other
   workers in the cluster until a replacement was spawned.

This mirrors how the Python agent handles the core-agent lifecycle:
launch it, forget the PID, let the daemon manage itself.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… instantly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…rker-owned

stopProcess() is now a no-op; no worker can kill the shared daemon.
allowShutdown had no documented behavior and no remaining effect.
Stripped from ScoutConfiguration type and all test callsites.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drop unused TimeoutError import
- Remove never-read socketConnected and socketConnectionAttempts fields
- Drop unused getPoolStats() private method
- Remove stale dangling comment above stopProcess()
- Drop unused result variable from socket.write() call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@jrothrock jrothrock force-pushed the fix/daemonize-core-agent branch from 6d14ae2 to 6663542 Compare May 29, 2026 22:56
@jrothrock jrothrock closed this May 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant