feat: --exit-confirmations, --watch-prompt-file, --no-classifier (v1.3.0)#14
Merged
JonyanDunh merged 1 commit intomainfrom Apr 12, 2026
Merged
Conversation
…3.0)
Three new flags for /watchdog:start, plus a small library refactor that
moves the prompt-file reader into a shared lib so the stop hook can
re-use it for hot-reload. Fully backward compatible: v1.2.4 state files
load with the new fields defaulted to their pre-1.3.0 values.
## What's new
- `--exit-confirmations <N>` (default 1) — require N **consecutive**
clean `NO_FILE_CHANGES` verdicts from the Haiku classifier before
the loop is allowed to exit. Strict-A reset semantics: any other
verdict (FILE_CHANGES / AMBIGUOUS / CLI_MISSING / CLI_FAILED) AND
any pure-text turn (no tool invocations) reset the streak counter
to 0. Convergence has to be unbroken to count.
- `--watch-prompt-file` — boolean flag, requires --prompt-file. The
Stop hook re-reads the prompt file at the start of every iteration.
If the content changed since the previous turn, the new version
becomes the next user turn AND the --exit-confirmations streak is
reset to 0 (a redefined task should not inherit convergence from
the old task). Hot-reload is silent on read failure: missing /
empty / unreadable file keeps the cached prompt and continues the
loop. Standalone --watch-prompt-file (no --prompt-file) is an
error.
- `--no-classifier` — disable the Haiku classifier entirely. The
Stop hook short-circuits before askHaiku() is ever called; the
loop only exits via --max-iterations or /watchdog:stop. The
`claude` CLI is not even required in this mode (the Haiku
subprocess is never spawned). Mutually exclusive with
--exit-confirmations (the streak counter is meaningless when no
classifier returns verdicts).
## Architecture
- New lib/prompt-file.js — shared readPromptFile() helper used by
both setup-watchdog.js (initial read) and stop-hook.js (hot-
reload). BOM strip, trim, ENOENT/EISDIR/EACCES error mapping,
resolved-path return value. setup-watchdog.js's inline copy is
removed.
- lib/state.js — create() now accepts exitConfirmations,
promptFile, watchPromptFile, noClassifier as named options. New
state file fields: `exit_confirmations` (int, default 1),
`no_change_streak` (int, default 0), `prompt_file` (string|null,
default null), `watch_prompt_file` (bool, default false),
`no_classifier` (bool, default false). isValid() unchanged so
existing v1.2.4 state files still load.
- hooks/stop-hook.js — major rewrite of the verdict handler:
* v1.3.0 fields read with defensive defaults so v1.2.4 state
files behave exactly as before
* Hot-reload happens early, before the max-iterations check, so a
fresh prompt-file content takes effect on the same iteration
that detects it
* --no-classifier short-circuit happens before askHaiku() so no
subprocess is ever spawned (not even a --version probe — but
we already removed that in 1.2.x)
* NO_FILE_CHANGES verdict now bumps the streak and only exits
when streak >= exit_confirmations; otherwise logs progress
(e.g. "1/3 - need 2 more, continuing loop") and re-feeds
* All non-NO_FILE_CHANGES verdicts and pure-text turns reset
effectiveStreak = 0 (strict-A semantics)
* iteration bump and streak/prompt persist happen in a single
update() patch to keep the atomic-write contract intact
- scripts/setup-watchdog.js — parses the three new flags. exit-
confirmations is left undefined when not passed (so we can tell
the difference between "user typed --exit-confirmations 1
explicitly" and "user left it off") and the validation checks
in main() use that distinction to error on
--no-classifier + --exit-confirmations conflict. resolvedPromptFile
captured at create-time so the hook's hot-reload doesn't have to
re-resolve a relative path against a possibly-different cwd later.
- commands/start.md, commands/help.md — argument-hint and full
reference updated to document all three new flags, mutual
exclusion rules, and the strict-A streak semantics. Requirements
table now notes the `claude` CLI is optional under
--no-classifier. Version anchor bumped 1.2.0 -> 1.3.0.
## Test plan
- [x] 124-test suite passes locally (124 active + 2 skipped-inside-
Claude-Code, 0 failures) — 30 net new tests since v1.2.4
- [x] setup.test.js: arg parse + validation for all new flags +
mutual exclusion + every error path
- [x] state.test.js: new fields default correctly, explicit values
stored, v1.2.4-shape state files still validated
- [x] stop-hook.test.js: backward-compat for v1.2.4 state files,
pure-text turn resets streak, --no-classifier short-circuits
Haiku (PATH stripped to prove no spawn attempt), --no-classifier
still respects --max-iterations, hot-reload happy/unchanged/
changed/deleted/empty/disabled paths
- [x] stop-hook-haiku.test.js: --exit-confirmations 3 streak
progression 1->2->3 then exit; FILE_CHANGES, AMBIGUOUS, FAIL
mid-streak each reset to 0; default-1 still exits on first
NO_FILE_CHANGES (regression check)
- [ ] CI will confirm on the standard matrix (ubuntu/macos/windows
× Node 18/20/22)
## What changed (file list)
- lib/prompt-file.js — NEW shared helper
- lib/state.js — extended create() schema
- scripts/setup-watchdog.js — three new flags, cross-flag validation,
uses shared prompt-file lib
- hooks/stop-hook.js — hot-reload, no-classifier, streak counter
- commands/start.md — argument-hint update
- commands/help.md — full new-flag reference + updated exit conditions
+ version anchor
- test/setup.test.js — +13 tests
- test/state.test.js — +3 tests
- test/stop-hook.test.js — +8 tests
- test/stop-hook-haiku.test.js — +5 tests
- README.{md,zh,es,ja,ko,vi,pt}.md — three new subsections under
Commands ("Stricter convergence with --exit-confirmations", "Hot-
reload the prompt mid-loop with --watch-prompt-file", "Disable
the classifier entirely with --no-classifier") and two new rows
("Convergence flexibility", "Prompt evolution") in the Watchdog
vs ralph-loop comparison table
- .claude-plugin/plugin.json — version 1.2.4 -> 1.3.0
- .claude-plugin/marketplace.json — version 1.2.4 -> 1.3.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three new flags for
/watchdog:startthat turn the loop's exit semantics into something you can actually tune. Fully backward compatible: v1.2.4 state files load with the new fields defaulted to their pre-1.3.0 values.What's new
--exit-confirmations <N>(default 1)Require N consecutive clean
NO_FILE_CHANGESverdicts from the Haiku classifier before the loop is allowed to exit. Strict reset semantics: any other verdict (FILE_CHANGES,AMBIGUOUS,CLI_MISSING,CLI_FAILED) and any pure-text turn (no tool invocations) reset the streak counter to0. Convergence has to be unbroken to count.Default
1is identical to pre-1.3.0 behavior, so an existing watchdog that didn't pass this flag continues to exit on the first clean verdict. Mutually exclusive with--no-classifier.--watch-prompt-file(boolean, requires--prompt-file)The Stop hook re-reads the prompt file at the start of every iteration. If the content has changed since the previous turn, the new version becomes the next user turn and the
--exit-confirmationsstreak counter is reset to0(a redefined task should not inherit convergence from the old task).Hot-reload never crashes the loop: missing / empty / unreadable file silently keeps the cached prompt and the loop continues. You can edit, rename, or temporarily move the file mid-loop without breaking anything. Standalone
--watch-prompt-file(no--prompt-file) is an error.--no-classifier(boolean)Disable the Haiku classifier entirely. The Stop hook short-circuits before `askHaiku()` is ever called; the loop only exits via `--max-iterations` or `/watchdog:stop`. The `claude` CLI is not even required in this mode (the Haiku subprocess is never spawned).
Compatible with
--prompt-fileand--watch-prompt-file. Mutually exclusive with--exit-confirmations— the streak counter is meaningless when no classifier returns verdicts.Architecture
lib/prompt-file.js— sharedreadPromptFile()helper used by bothsetup-watchdog.js(initial read) andstop-hook.js(hot-reload). Centralized BOM strip, trim, ENOENT/EISDIR/EACCES error mapping, resolved-path return value. The inline copy in setup-watchdog.js is removed.lib/state.js—create()accepts `exitConfirmations`, `promptFile`, `watchPromptFile`, `noClassifier` as named options. New state file fields (`exit_confirmations`, `no_change_streak`, `prompt_file`, `watch_prompt_file`, `no_classifier`) all default to backward-compatible values. `isValid()` is unchanged so existing v1.2.4 state files still load.hooks/stop-hook.js— major rewrite of the verdict handler:--no-classifiershort-circuit happens before `askHaiku()` so no subprocess is ever spawnedNO_FILE_CHANGESverdict bumps the streak and only exits when `streak >= exit_confirmations`; otherwise logs progress (e.g. "1/3 - need 2 more, continuing loop") and re-feedsBackward compatibility
exit_confirmations=1,no_change_streak=0,no_classifier=false,watch_prompt_file=false,prompt_file=null. Behavior is bit-for-bit identical to v1.2.4./watchdog:start \"prompt\"callsVerified by running the entire pre-existing test suite unmodified plus 30 new tests.
Test plan
Scope
Install / upgrade
```bash
/plugin marketplace update claude-code-watchdog
/reload-plugins
```
Verify with `/watchdog:help` — look for the three new options under `/watchdog:start`.
Co-Authored-By: Claude Opus 4.6 (1M context) noreply@anthropic.com