SOP: Open-threads channel-state mechanism
Why this exists
Ray sends asks (questions, decision-needed prompts, "want me to" framings) through iMessage and Discord. When founder is busy / asleep / context-switched, asks sit unanswered indefinitely with no visibility ā they age out of his head AND Ray's head. Gap #4 in the COO-agent unhobbling backlog.
Solution: channel-as-state parking. The channel IS the durable record. Ray watches for own-asks that have aged past a cooldown threshold and parks them with a recognizable marker. Morning brief surfaces parked threads. Founder can also ask on-demand.
Mechanics
Parking marker
All parking notes begin with the parked-letter emoji š
æļø (U+1F17F). Same character for iMessage and Discord. Format:
š
æļø Parking [<short topic>] for now. Resurfacing in morning brief.
<short topic> = 3-7 word distillation of the ask Ray was waiting on.
Anti-double-fire
The parking-check cron skips any channel where Ray's most-recent message already begins with š
æļø. This is the entire dedup mechanism ā no state file needed.
Cooldown thresholds
| Time of day (America/New_York) | Behavior |
|---|---|
| 9am-9pm ET (any day, including weekends) | If Ray's last message is older than 60min AND contains an ask, fire parking note |
| 9pm-9am ET | No firing ā defer to next 9am ET |
Cooldown is wall-clock age of Ray's last message, not time-since-ask-was-sent (in practice these are the same since the ask IS Ray's last message in the trigger scenario).
Ask detection (LLM judgment inside the skill)
The check skill is a Claude session, so detection is structured judgment, not regex. An "ask" is any of:
- Direct non-rhetorical question (
?) - Decision-needed framing: "want me to X?", "should I/we", "your call", "approve?", "go/no-go", "thoughts?"
- Options-pick: "two paths: A or B", "options: 1, 2, 3", explicit numbered choice
- Implicit handoff: "let me know when you've decided"
NOT asks (no parking):
- Pure status: "Done. Filed at X."
- FYI: "Heads up ā Y happened."
- Acknowledgment: "Got it."
- Ray's own follow-up answering his earlier ask
Conservative bias: when ambiguous, DO NOT park. False-negative (missed park) is recoverable ā founder can ask "what's open?". False-positive (park where founder isn't blocked) creates noise.
Tracked channels (v1)
- iMessage: founder DM at
any;-;+18595834595(canonical per CLAUDE.md hard-rules). - Discord: any channel where Ray is operationally active. Add Discord channel IDs to this section as they become tracked.
To add a channel: append channel ID + label to this section. The /open-threads-check skill reads this SOP for the enumeration.
Morning-brief integration
The /morning-prep skill (step 5.5) queries each tracked channel for messages from the last 24h whose first character is š
æļø. Surfaces them in a single "OPEN THREADS PARKED OVERNIGHT" section directly above SUGGESTED FOCUS. One line per parked thread. Section omitted if no parked threads.
On-demand resurface
When founder asks "what's open?", "where did we leave off?", "show parked threads", or similar ā any session-active Claude reads tracked channels for š
æļø-prefix messages within the last 7d and surfaces them chronologically. No dedicated skill; it's a documented pattern.
Cleanup
None. When founder responds to a parked thread, the thread is functionally un-parked because Ray's next reply won't start with š
æļø and the cooldown clock resets on the next inbound message. Old parking notes stay in channel history as a free audit trail. The 7d window is the surfacing horizon, not a deletion threshold.
Failure modes + recovery
| Failure | Recovery |
|---|---|
| Skill fires false-positive (parks something founder wasn't blocked on) | Founder ignores or replies "not parked, I had it". Ray adjusts ask-detection heuristic. |
| Skill misses an obvious ask (false-negative) | Founder asks "what's open?". Ray surfaces from channel history (which still has the un-parked ask). |
| Two parking notes in a row in same channel | Anti-double-fire failed. Investigate: likely cron fired twice in same 15min window OR marker char got mangled. Check ~/.claude/state/check-board-cycle-log.md for cron timing. |
| Morning brief surfaces a thread founder already resolved | Founder resolution wasn't recognized as a "thread response". Tune morning-prep step 5.5 to also check for founder replies AFTER the parking note. |
Related
- [[~/.claude/skills/open-threads-check/SKILL.md]] ā the cron skill
- [[~/.claude/skills/morning-prep/SKILL.md]] ā consumes parking notes in morning brief
- [[~/.claude/projects/-Users-ray/memory/feedback_open_threads_channel_state.md]] ā feedback memory loaded every session
- [[~/.claude/scripts/scheduled-jobs.txt]] ā cron entry
- [[~/.claude/state/implementation-notes-open-threads-channel-state.md]] ā build implementation notes
Source
- Founder design lock: iMessage 2026-05-18 21:38 ET ("Sounds useful though. Can you get it done please?") after 4 iterations on cooldown thresholds, marker convention, and morning-brief integration.
- Pattern shape: channel-as-state, no state file ā chosen explicitly to keep the system debuggable by founder scrolling channel history.