sloop-daemon 0.5.0

Agentic coding scheduler — a daemon that runs background coding agents autonomously in isolated git worktrees
Documentation
version: 1
vendor: claude
# `claude --output-format stream-json` emits one JSON record per line, and the
# stream carries both directions: the vendor's own messages *and* every file
# the agent read back through a tool. Without framing the classifier cannot
# tell them apart, so an agent reading a fixture that quotes a rejection reads
# as the vendor issuing one.
framing: ndjson
rules:
  - id: claude.rate-limit.usage-limit
    class: rate_limited
    diagnostic: Claude usage limit reached
    match:
      # No stream constraint: the vendor's refusal arrives on stdout as a
      # synthetic assistant message, so a stderr-only rule is unreachable here.
      #
      # Only the vendor authors these two records. `is_api_error_message` marks
      # the synthetic message; the result record's `is_error` is the vendor's
      # own top-level verdict on the run. Predicates read top-level fields, so
      # a rejection quoted inside a tool result — an escaped string in some
      # other record's field — never satisfies either. Lines that are not JSON
      # stay eligible, which keeps the buffered `--print` form classifying.
      record_any_of:
        - is_api_error_message: true
        - type: result
          is_error: true
      # Signatures are conjunctive, so the one signature has to be the wording
      # every limit shares. Claude qualifies the noun per limit window
      # ("your limit", "your session limit", "your weekly limit"); the phrase
      # up to that qualifier is what stays constant.
      message_signatures:
        - You've hit your
  - id: claude.rate-limit.api-overloaded
    class: rate_limited
    diagnostic: Claude API overloaded
    match:
      # Observed as `API Error: 529 Overloaded. This is a server-side issue,
      # usually temporary — try again in a moment.` A transient server-side
      # overload, not a usage limit, but it earns the same conservative
      # treatment: back off and retry later.
      record_any_of:
        - is_api_error_message: true
        - type: result
          is_error: true
      message_signatures:
        - 529 Overloaded