diff --git a/CLAUDE.md b/CLAUDE.md index 913063d..9239c14 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,7 +30,10 @@ Because this cycle now runs with the full tool access of the invoking context (n 1. Ensure the cycle keeps triggering on its own, without depending on the model remembering to do so: call `CronList` to check whether a recurring job invoking `/hermit` (or this cycle) is already scheduled. - If no such job is registered, call `CronCreate` to schedule one at the configured interval (e.g. `*/2 * * * *` for the default 120-second cadence; round to the nearest whole minute the cron expression can express) - If a matching job is already registered, do nothing -2. If a `.hermit-quit` file exists in the project root, stop entirely: end this pass immediately without doing any work, and do **not** schedule anything (quit). This is a terminal stop, unlike pause — it is not resumed by `hermit resume`; starting `/hermit` again is required to resume autonomous operation. +2. If a `.hermit-quit` file exists in the project root, stop entirely — and actually cancel the recurring trigger, not just this one pass: + - Call `CronList` to find the recurring job invoking `/hermit` (registered in step 1), and call `CronDelete` on it. Do **not** just skip scheduling and leave a previously-registered job in place — an existing session-only cron job keeps firing `/hermit` every tick regardless of what a given pass does, so leaving it running means every subsequent tick wastes a full pass re-detecting the same quit file until the job is explicitly deleted (or the session expires after 7 days). + - If instead this project is run via `hermit run` (the standalone OS-process loop from Issue #181/PR #189, not a Claude-session cron job), no action is needed here: `hermit run` already watches for `.hermit-quit` itself (`internal/runloop/runloop.go`) and stops its own tick loop when the file appears — it does not register or depend on session-only `CronCreate`/`CronList`/`CronDelete` jobs at all, so this step's `CronDelete` call is a no-op (or simply finds nothing) in that mode. To fully stop a `hermit run` process, use its own controls; `.hermit-quit` alone is sufficient because `hermit run` checks for it directly. + - Then end this pass immediately without doing any other work, and do **not** schedule a new job (quit). This is a terminal stop, unlike pause — it is not resumed by `hermit resume`; a human must delete `.hermit-quit` and then start `/hermit` again (which re-runs step 1 and re-registers the recurring job) to resume autonomous operation. 3. If a `.hermit-paused` file exists in the project root, end this pass immediately without doing any work (paused) — the recurring cron trigger re-checks on the next cycle 4. Retrieve open Issues with `list_issues` 5. Check open PRs for new review comments using `get_recent_pr_comments` with a `since` timestamp set to the last check time (store the current time before calling): diff --git a/cmd/hermit/templates/CLAUDE.md.tmpl b/cmd/hermit/templates/CLAUDE.md.tmpl index 2431c77..150c21f 100644 --- a/cmd/hermit/templates/CLAUDE.md.tmpl +++ b/cmd/hermit/templates/CLAUDE.md.tmpl @@ -13,7 +13,10 @@ 1. Ensure the cycle keeps triggering on its own, without depending on the model remembering to do so: call `CronList` to check whether a recurring job invoking `/hermit` (or this cycle) is already scheduled. - If no such job is registered, call `CronCreate` to schedule one at the configured interval (e.g. `*/2 * * * *` for the default 120-second cadence; round to the nearest whole minute the cron expression can express) - If a matching job is already registered, do nothing -2. If a `.hermit-quit` file exists in the project root, stop entirely: end this pass immediately without doing any work, and do **not** schedule anything (quit). This is a terminal stop, unlike pause — it is not resumed by `hermit resume`; starting `/hermit` again is required to resume autonomous operation. +2. If a `.hermit-quit` file exists in the project root, stop entirely — and actually cancel the recurring trigger, not just this one pass: + - Call `CronList` to find the recurring job invoking `/hermit` (registered in step 1), and call `CronDelete` on it. Do **not** just skip scheduling and leave a previously-registered job in place — an existing session-only cron job keeps firing `/hermit` every tick regardless of what a given pass does, so leaving it running means every subsequent tick wastes a full pass re-detecting the same quit file until the job is explicitly deleted (or the session expires after 7 days). + - If instead this project is run via `hermit run` (the standalone OS-process loop from Issue #181/PR #189, not a Claude-session cron job), no action is needed here: `hermit run` already watches for `.hermit-quit` itself (`internal/runloop/runloop.go`) and stops its own tick loop when the file appears — it does not register or depend on session-only `CronCreate`/`CronList`/`CronDelete` jobs at all, so this step's `CronDelete` call is a no-op (or simply finds nothing) in that mode. To fully stop a `hermit run` process, use its own controls; `.hermit-quit` alone is sufficient because `hermit run` checks for it directly. + - Then end this pass immediately without doing any other work, and do **not** schedule a new job (quit). This is a terminal stop, unlike pause — it is not resumed by `hermit resume`; a human must delete `.hermit-quit` and then start `/hermit` again (which re-runs step 1 and re-registers the recurring job) to resume autonomous operation. 3. If a `.hermit-paused` file exists in the project root, end this pass immediately without doing any work (paused) — the recurring cron trigger re-checks on the next cycle 4. Retrieve open Issues with `list_issues` 5. Treat any Issue labeled `requirements` (or whose title starts with `[Requirements]`) as a **standing requirements-hearing channel**, not a work item — this is where non-engineers converse with HERMIT to create/update the requirements document. Exclude these Issues from the Engineer-spawning steps below (steps 7–8), and instead: