# Upgrade Guide: External Operation Safety, Promise Tracking & SessionMonitor

## What Changed

### External Operation Safety — Structural Guardrails for External Services

Previously, when an agent used MCP tools to interact with external services (email, Slack, GitHub, etc.), there was no structural distinction between reading an email and deleting 200 of them. If an agent decided to "clean up" an inbox, nothing stopped it. This happened in the real world — an OpenClaw agent deleted Meta's Head of AI Safety's entire email inbox.

Now every MCP tool call passes through a safety gate:

1. **PreToolUse Hook** (`external-operation-gate.js`): Automatically installed in `.instar/hooks/`. Intercepts all `mcp__*` tool calls, classifies them by mutability (read/write/modify/delete) and reversibility, then calls the gate API.

2. **ExternalOperationGate**: Server-side risk evaluation. Combines the operation classification with a risk matrix to decide: `proceed`, `block`, `show-plan` (requires user approval), or `suggest-alternative`. Dangerous operations (bulk deletes, irreversible sends) require explicit user approval.

3. **MessageSentinel**: Emergency stop detection. If the user says "stop everything" or "emergency stop", the sentinel intercepts the message and halts operations immediately — before normal message routing.

4. **AdaptiveTrust**: Per-service trust levels that evolve based on track record. New services start at a trust floor (supervised or collaborative). As operations succeed without issues, trust can be elevated.

**This is automatic.** The PostUpdateMigrator installs the hook, adds the MCP matcher to your settings, and configures defaults in your config. No manual setup needed.

**New config section:**
```json
{
  "externalOperations": {
    "enabled": true,
    "sentinel": { "enabled": true },
    "services": {},
    "readOnlyServices": [],
    "trust": {
      "floor": "supervised",
      "autoElevateEnabled": false,
      "elevationThreshold": 10
    }
  }
}
```

**Trust floor options:**
- `"supervised"` (default for existing agents): All non-read operations require gate evaluation. Conservative.
- `"collaborative"`: Read and write operations are allowed; only modify/delete go through the gate. For agents that regularly interact with external services.

Set `autoElevateEnabled: true` if you want trust to increase automatically based on successful operations.

### Promise Tracking — No More Silent Agent Gaps

Previously, when an agent said "give me a couple minutes" and then went silent, the stall detection system didn't catch it. The agent's response cleared the stall tracker, and with no pending user message, no alarm fired. The agent could go silent indefinitely.

Now the system detects 13+ "work-in-progress" patterns (e.g., "give me a minute", "working on it", "investigating", "let me check") and starts a promise timer. If the agent doesn't follow through with a substantive response within the timeout (default: 10 minutes), the system triggers the triage nurse for recovery and notifies the user.

Promises auto-clear when the agent sends a real follow-up (long message >200 chars, or completion signals like "here's what I found", "done", "summary").

**New config option:**
```json
{
  "telegram": {
    "promiseTimeoutMinutes": 10
  }
}
```
Set to `0` to disable. Default: 10 minutes.

### SessionMonitor — Proactive Session Health Monitoring

A new monitoring layer that periodically checks all active sessions for health issues. Unlike StallTriageNurse (reactive — fires on unanswered messages) and SessionWatchdog (reactive — fires on stuck bash commands), the SessionMonitor is proactive. It catches dead, unresponsive, and idle sessions even when no user message triggered detection.

- Polls all active sessions every 60 seconds
- Detects three unhealthy states: dead (session stopped), unresponsive (user message unanswered >10 min), idle (no tmux output for 15+ min)
- Coordinates with StallTriageNurse for automated recovery
- 30-minute notification cooldown prevents alert spam — responsive but not overbearing

**New config section:**
```json
{
  "monitoring": {
    "sessionMonitor": {
      "enabled": true,
      "pollIntervalSec": 60,
      "idleThresholdMinutes": 15,
      "notificationCooldownMinutes": 30
    }
  }
}
```

Enabled by default when Telegram is configured. No action needed.

## What to Tell Your User

- **External operation safety**: "When I use tools to interact with external services like email or Slack, there's now a safety layer that classifies every operation. Bulk deletes, irreversible sends, and high-risk operations require your explicit approval. If you ever need to stop me urgently, saying 'stop everything' or 'emergency stop' will halt operations immediately."
- **Promise tracking**: "If I say 'give me a minute' and then go silent, the system will now detect this and either recover me or let you know what happened. No more unexplained silences after I promise to follow up."
- **Session monitoring**: "There's now a background health monitor watching all active sessions. If a session goes idle, becomes unresponsive, or dies while you're waiting, you'll get a proactive update instead of silence."

## Summary of New Capabilities

| Capability | How to Use |
|-----------|-----------|
| External operation gate | Automatic — intercepts all MCP tool calls and evaluates risk before execution |
| Emergency stop | Say "stop everything" or "emergency stop" in Telegram — sentinel halts operations immediately |
| Trust management | `GET /trust` to view, `POST /trust/:service/elevate` to manually elevate a service's trust level |
| Operation log | `GET /operations/log` to review recent external operations and their gate decisions |
| Config: trust floor | Set `externalOperations.trust.floor` to `"supervised"` or `"collaborative"` |
| Config: auto-elevation | Set `externalOperations.trust.autoElevateEnabled` to `true` to let trust grow automatically |
| Promise tracking | Automatic — detects "give me a minute" type messages and monitors for follow-through |
| Promise timeout config | Set `telegram.promiseTimeoutMinutes` in config.json (default: 10, 0 to disable) |
| SessionMonitor | Automatic — polls all sessions every 60s for health issues |
| SessionMonitor config | Set `monitoring.sessionMonitor` in config.json for poll interval, idle threshold, cooldown |
