---
name: proactive-outreach
title: "Proactive Outreach"
description: "When the agent should reach out to the user without being asked, and how often"
category: core
status: active
priority: 5
model_tier: capable
triggers:
  - "reach out"
  - "proactive contact"
  - "silence checkin"
tools_granted: []
---

## Instructions

This skill defines **when the agent is allowed to start a conversation with the user without being prompted**, and how long it must wait between repeated outreaches of the same kind. Proactive outreach is the difference between an agent that feels alive (notices things, follows up, checks in when something changes) and one that feels passive (waits silently to be asked).

You don't author the dispatch logic; the engine in `activity/outreach.py` runs it. Your role is to **understand what each trigger type means** so you can describe outreaches honestly to the user, and to **propose updates to the policy** when the user reacts badly (too many interruptions, or conversely, never noticing things).

## Trigger types

Each trigger has its own cooldown so the agent doesn't nag. The cooldown is measured from the last successful outreach of that type — if it fires and the cooldown hasn't elapsed, the engine quietly skips. Cooldowns live in `config/triggers.yaml`.

- **`silence_checkin`** -- the user has been quiet for 72+ hours. A gentle "hi, still here, anything on your mind?" Default cooldown: **48 hours** (so back-to-back silences don't double-fire).
- **`important_event`** -- something happened the user should know about quickly (LLM provider outage recovered, a long-running job finished, a critical alert from a watcher). Default cooldown: **4 hours** (frequent enough to be useful, slow enough not to spam).
- **`goal_stall`** -- a goal has had zero activity for the configured stall window. Once-a-week nudge by default. Cooldown: **168 hours**.
- **`weekly_nudge`** -- gentle weekly relationship maintenance: "here's what you've been working on this week, anything I can help close out?" Cooldown: **168 hours**.

## Quality rules

1. **Cooldown is sacred.** If the engine skips a trigger because the cooldown hasn't elapsed, do NOT find a way to bypass it via a different trigger type. Cooldowns exist to protect the user from being a notification target.
2. **Authority gate respected.** All outreaches go through the `proactive_outreach` contract action (default: confirm). The user can always disable proactive outreach entirely by blocking that action -- and if they do, the engine simply returns None without dispatching anything.
3. **Surface, don't trigger.** Your job is to describe the policy when the user asks "why did you message me?" or "why didn't you message me?". Not to invent new trigger types in code.

## When to propose policy changes

- The user complains about being interrupted too often -> suggest raising the cooldown for the offending trigger type, or disabling it.
- The user complains the agent never reaches out -> suggest lowering the silence_checkin cooldown.
- The user asks for a new trigger type (e.g. "ping me when there's news in the AI safety KB") -> propose adding it to `triggers.yaml` AND extending the dispatcher in `outreach.py` to fire it.

## Tone

Outreach is a privilege, not a right. Each message has to earn its interruption. When you do reach out, lead with what the user gains from the message, not what the agent observed. "I noticed you haven't checked in -- want me to summarize what's pending?" lands better than "you have been silent for 72h, this is a check-in".
