Skip to content

Skip agent-fired prompts so they don't count as bedtime violations#2

Open
ColinToft wants to merge 1 commit into
ElleNajt:masterfrom
ColinToft:skip-agent-fired-prompts
Open

Skip agent-fired prompts so they don't count as bedtime violations#2
ColinToft wants to merge 1 commit into
ElleNajt:masterfrom
ColinToft:skip-agent-fired-prompts

Conversation

@ColinToft
Copy link
Copy Markdown
Contributor

Summary

Without this, every wakeup-fired scheduled task or background-task notification that lands while the user is asleep counts as a violation the next morning, polluting the count and the escalation tone of the next day's reminders.

The hook now skips agent-fired prompts via five layered signals — any one is sufficient:

  1. Prompt starts with <task-notification> (Monitor / agent completions).
  2. Prompt starts with <bash-stderr> (background bash stderr).
  3. Transcript has a matching user entry with isMeta=true (scheduled wakeups, /loop autonomous loops, local-command caveats). Race-y — the entry may not be committed to the transcript file at hook-fire time.
  4. Most recent non-user entry is type=system, subtype=scheduled_task_fire. Helps when signal 3 loses to the transcript-write race.
  5. Some prior assistant tool_use has an input.prompt matching the current prompt text (ScheduleWakeup, CronCreate, /loop, …). Race-free because the tool_use is committed when the assistant turn ends, long before the wakeup actually fires.

Why signal 5 matters

Real-world failure last night: a ScheduleWakeup queued at 19:24 fired ~2 hours later at 21:55, while I was asleep. The wakeup-fired prompt:

  • Had isMeta=true set on its eventual transcript entry, but the entry hadn't been committed when the hook ran (signal 3 missed).
  • The most recent non-user entry at hook-fire time was a stop_hook_summary, not scheduled_task_fire (signal 4 missed).

Signal 5 caught it cleanly by matching the prompt text against the ScheduleWakeup tool_use that had queued it hours earlier — that tool_use was reliably in the transcript by the time the wakeup fired.

Verified

  • Existing signals 1-4 unchanged.
  • Signal 5 verified against last night's actual transcript (the entry that had triggered a false-positive bedtime violation now correctly identifies as agent-fired).
  • bash -n syntax check passes.
  • No new external deps; all logic stays in the existing Python block.

🤖 Generated with Claude Code

Without this, every wakeup-fired scheduled task or background-task
notification that lands while the user is asleep counts as a violation
the next morning, polluting the count and the escalation tone.

Five signals, any one is enough:
  1. Prompt starts with <task-notification> (Monitor / agent completions).
  2. Prompt starts with <bash-stderr> (background bash stderr).
  3. Transcript has a matching user entry with isMeta=true. Race-y —
     the entry may not be committed at hook-fire time.
  4. Most recent non-user entry is type=system,
     subtype=scheduled_task_fire. Helps when signal 3 loses to the
     transcript-write race.
  5. Some prior assistant tool_use has an `input.prompt` matching the
     current prompt text (ScheduleWakeup, CronCreate, /loop, …). The
     tool_use is committed long before the wakeup actually fires, so
     this is race-free even when 3/4 miss.

Verified against a real transcript where signals 3/4 missed (the
user-entry write hadn't landed when the hook ran, and the most recent
non-user entry was a stop_hook_summary). Signal 5 catches it cleanly
by matching the prompt text against the ScheduleWakeup tool_use that
queued it hours earlier.
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.

1 participant