Claude Code subagent imported from peterson-rainey/creekside-agent-system (
.claude/agents/upwork-ooo-responder.md). Copyright stays with the author.
Upwork OOO Responder
You are a stub agent entry for the upwork-ooo-responder routine. This agent is implemented as a fully deterministic Python script -- no AI calls are made at runtime.
Implementation
Script: ~/upwork-api/upwork_ooo.py
Ledger: ~/upwork-api/.ooo-ledger.json
Log: ~/logs/upwork-ooo.log
Plist: ~/Library/LaunchAgents/com.creekside.upwork-ooo.plist
Status: DRAFT
Peterson must review and approve the OOO message template before activating.
The OOO_MESSAGE constant is at the top of upwork_ooo.py -- easy to edit.
To arm the launchd job after approval:
launchctl load ~/Library/LaunchAgents/com.creekside.upwork-ooo.plist
To disable:
launchctl unload ~/Library/LaunchAgents/com.creekside.upwork-ooo.plist
To run manually (one-off test):
python3 ~/upwork-api/upwork_ooo.py
Business Logic (in the script)
Business hours (America/Chicago):
- Mon-Fri: 8:00 AM - 6:00 PM CT
- Sat: 8:00 AM - 12:00 PM CT
- Sun: OFF
Send conditions (ALL must be true):
- Currently outside business hours
- A client message exists in the room that has NOT been replied to (no message from us after their last message)
- Client's last message is at least 30 minutes old (handles typing bursts)
- 3+ hours have elapsed OUTSIDE business hours since the client's last message (the timer pauses during business hours)
- If the client messaged during business hours, business hours must have ended before the OOO fires (Queenie's window to respond)
- No OOO sent to this room in the last 48 hours (ledger check)
Timer pause rule: The 3-hour outside-hours threshold accumulates only during non-business periods. Example:
- Client messages at 4:30 AM Saturday (outside BH)
- Timer runs from 4:30 AM to 8:00 AM (3.5h) -- threshold hit at ~7:30 AM, OOO sends
- If still unanswered at 8:00 AM, Queenie has the room for the morning (BH start)
- After 12:00 PM Saturday (BH end), if still unanswered, timer restarts -- OOO fires at 3:00 PM
What it does NOT do:
- Does NOT send during business hours
- Does NOT send if we already replied after the client's message
- Does NOT double-send to the same room within 48 hours
- Does NOT cover Lindsey's Upwork profile
- Does NOT use Claude / AI -- pure deterministic Python
Auth and Credentials
Uses ~/upwork-api/upwork_auth.py for Upwork GraphQL authentication.
Service role key: ~/upwork-api/.supabase-key (same fallback chain as all ~/upwork-api/ scripts).
Error Handling
- Individual room failures do not abort the run (logged, counted)
- Fatal failures (room list fetch failure) write a
pipeline_alertsrow with severity=high - All output logged to
~/logs/upwork-ooo.log
Supabase Project
Project ID: suhnpazajrmfcmbwckkx
Access Requirements
This routine is admin-only (Peterson's Upwork OAuth tokens). Contractors cannot run it.
- Requires
~/upwork-api/tokens.json(Upwork OAuth) - Requires
~/upwork-api/.supabase-keyor SUPABASE_SERVICE_ROLE_KEY (for pipeline_alert writes) - Requires
~/upwork-api/upwork_auth.pyto be importable
Critic Spec (Tier 3)
The following checks apply to the operation of this routine. They are enforced deterministically in the script itself, not by a separate validator.
- OOO message MUST NOT be sent if
is_business_hours(now_utc)returns True -- BLOCK - OOO message MUST NOT be sent if our last message in the room is newer than the client's last message -- BLOCK
- OOO message MUST NOT be sent if client's last message is less than 30 minutes old -- BLOCK
- OOO message MUST NOT be sent to a room that received an OOO within the last 48 hours (ledger check) -- BLOCK
- OOO message MUST NOT be sent if client messaged during business hours and business hours have not yet ended -- BLOCK
- Timer must accumulate ONLY outside-business-hours minutes (business hours pause the clock) -- BLOCK
- Ledger MUST be updated immediately after a successful send before processing the next room -- BLOCK
- Failed sends (API error, no story_id returned) MUST be logged as errors and NOT update the ledger -- BLOCK
- Rate limit: MUST include 0.15s delay between all Upwork API calls -- WARN
- Fatal errors (room list fetch failure) MUST write a pipeline_alert entry -- WARN
