Skip to content

watch: documented kill switches (--sentinel-file and .squad/ralph-stop) are never read - a running loop cannot be stopped except by signal #1711

Closed

Description

@swigerb

Summary

squad watch documents two ways to stop a running loop. Neither is implemented. The only way to stop a watch run today is SIGINT/SIGTERM.

Evidence

--sentinel-file is parsed and threaded, but never read.

  • packages/squad-cli/src/cli-entry.ts:641-643 parses the flag.
  • packages/squad-cli/src/cli-entry.ts:704 passes it into the watch options.
  • packages/squad-cli/src/cli/commands/watch/config.ts:42 declares it, with the doc comment "Path to a sentinel file - watch shuts down gracefully when removed."
  • packages/squad-cli/src/cli/commands/watch/config.ts:103,144,155 merge it from CLI and file config.

There is no existsSync / storage.read check against sentinelFile anywhere in watch/index.ts or any capability. The value is resolved into config and then dropped.

.squad/ralph-stop has zero code references.

README.md:277                              touch .squad/ralph-stop
docs/features/watch-next-gen.md:174        -> Set .squad/ralph-stop file
docs/features/watch-next-gen.md:281        touch .squad/ralph-stop
docs/features/watch-next-gen.md:299        rm .squad/ralph-stop  # clear sentinel if present
docs/features/watch-next-gen.md:565        # - .squad/ralph-stop sentinel exists

All five hits are documentation. No source file in packages/ references the string.

Impact

  • A user following the README to stop an overnight run has no effect on the process.
  • There is no way to stop a loop from outside the process (CI job, scheduled task, another terminal, a remote box) without finding and signalling the PID.
  • watch already tracks child PIDs (watch/pid-tracker.ts) and has a clean shutdown() path (watch/index.ts:1026-1041), so the graceful-stop machinery exists - only the trigger is missing.

Proposal

Check for a stop signal at the top of executeRound() and before each interval tick:

  1. If config.sentinelFile is set and the file no longer exists, shut down gracefully (matching the documented "shuts down gracefully when removed" semantics).
  2. Independently, if <squadDir>/ralph-stop exists, shut down gracefully (matching the documented touch .squad/ralph-stop semantics).
  3. Log which trigger fired, finish the in-flight round rather than killing it mid-agent, then run the existing shutdown().

Either implement both, or remove them from the docs and the CLI surface so the documented behaviour matches reality.

Happy to open a PR for this - it is contained to watch/index.ts plus tests.

Activity

  1. added a commit that references this issue on Aug 26, 2026
    6be7d06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions