Skip to content

fix(sa-implement): keep daemon alive on empty backlog in continuous mode - #15

Merged
sh1ningwang merged 2 commits into
developfrom
fix/sa-implement-daemon-liveness
Jun 14, 2026
Merged

fix(sa-implement): keep daemon alive on empty backlog in continuous mode#15
sh1ningwang merged 2 commits into
developfrom
fix/sa-implement-daemon-liveness

Conversation

@sh1ningwang

Copy link
Copy Markdown
Owner

Summary

Fixes the sa-implement daemon exiting the moment the GitHub issue backlog is empty in normal
continuous mode. It now idle-polls an empty backlog and stays alive until an explicit user stop,
the kill-switch, a time/PR/escalation budget, or single-shot --once.

What this PR does

  • bin/auto-daemon.sh — in daemon_loop's gate-stop handler, treat backlog-empty as
    non-terminal when --once was not passed, falling through to the existing idle-poll. Every
    other stop reason stays terminal; --once still stops on empty. The gate's contract is
    unchanged (a gate-side flag was rejected by review as incomplete — a second STOP backlog-empty fires after the gate's idle-backoff).
  • SKILL.md — clarify backlog-empty is terminal only under --once.
  • lib/gh.sh — correct the stale gh_queue_list doc comment (it accepts an assignee arg).

Verification

Deterministic harness (no live GitHub): real auto-gate.sh decision table 8/8; real
daemon_loop driven through its FIFO protocol 10/10 in fixed-mode (incl. a full
idle → work → idle → explicit-stop lifecycle). Pre-fix code reproduces the exit-on-empty bug.

Closes #14

sh1ningwang and others added 2 commits June 14, 2026 03:01
The long-running daemon is meant to idle-poll an empty backlog (~15m) and
terminate only on an explicit user stop, the kill-switch, a time/PR/escalation
budget, or single-shot --once. In practice it exited the moment the backlog
drained in normal continuous mode.

daemon_loop calls auto-gate.sh with --no-backoff, which makes the gate emit
"STOP backlog-empty" on an empty queue. The daemon treated any gate STOP as
terminal and returned, so it exited as soon as the backlog was empty; its own
idle-poll branch was correct but unreachable.

Fix it daemon-side (the daemon owns cadence): in the gate-stop handler, treat
"backlog-empty" as NON-terminal when --once was not passed, falling through to
the existing idle-poll. Every other stop reason (kill-switch/time/budget/
operator) stays terminal, and --once still stops on an empty backlog. A
gate-side flag was rejected by review as incomplete (a second STOP backlog-empty
fires after the gate's idle-backoff), so the gate's contract is left unchanged.

Also clarify the backlog-empty wording in SKILL.md (terminal only under --once)
and correct the stale gh_queue_list doc comment (it accepts an assignee arg).

Verified with a deterministic harness (no live GitHub): the real auto-gate.sh
decision table (8/8) and the real daemon_loop driven through its FIFO protocol
(fixed-mode 10/10, incl. a full idle -> work -> idle -> explicit-stop lifecycle);
the pre-fix code reproduces the exit-on-empty bug.

Closes #14
@sh1ningwang
sh1ningwang merged commit 4e1f56a into develop Jun 14, 2026
1 check passed
@sh1ningwang
sh1ningwang deleted the fix/sa-implement-daemon-liveness branch June 14, 2026 06:39
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.

fix(sa-implement): daemon exits on empty backlog in continuous mode

1 participant