02-sops

open threads channel state mechanism

2026-05-18·sop·status: active

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:

NOT asks (no parking):

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)

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

Source