Stage Manager

When the renewal goes quiet, page the owner — not the customer.

Every company pages an engineer when a server goes down. Almost nobody pages the human who owns the account. PagerDuty phones you to acknowledge an alert. Ack is not a decision — we capture one in about sixty seconds.

Scroll for the cue sheet

Slack can wait. This account can’t.

Support loops. SLA turns red. An agent hits needs_human. Health stalls before renewal. Chat notifications hide. Phone doesn’t — if the call is rare, short, and for the right person. We enforce a per-owner call budget so “rare” is policy, not a hope.

One engine. Four cues.

  1. Cue arrives (fixture, stdin, or POST /cue)
  2. Call sheet — owned? severity? quiet hours? owner budget?
  3. Dress rehearsal (dry-run) by default — or curtain up (live call)
  4. Identity — spoken stage code (binds the decision to the call-sheet owner)
  5. Line reading — a 1 / 2 / 3 decision menu on the CS phone
  6. Prompt book (audit log) + action intent (system handoff)

stuck_support

Take over in chat now · Assign to SE / specialist · Not now — snooze 2 hours

agent_needs_decision

Approve A — allow the one-time exception · Approve B — require the signed amendment first · Reject — escalate to manager

sla_risk

I own this ticket now · Page backup CS/SE · Acknowledge risk, no action

health_onboarding

Book SE technical session · Mark watchlist — no outreach yet · Flag churn risk for manager

How judges run this

Clone → dress rehearsal (no key) → action-intent dry-run → optional curtain-up.

git clone https://github.com/assafbar2/customer-success-voice-signal-hackathon.git
cd customer-success-voice-signal-hackathon/skills/customer-success-voice-signal
npm install

# Dress rehearsal — default, no ring
npm run signal -- --fixture stuck_support_acme.json
npm run signal -- --stdin < events/webhook_stuck_support.json

# Or: HTTP inbound (same engine)
npm run serve-cue &
curl -sS -X POST http://127.0.0.1:8787/cue \
  -H 'content-type: application/json' \
  -d @events/webhook_stuck_support.json

# Decision → system handoff (Slack/GitHub live when env set)
npm run apply-action -- --last --dry-run
npm run apply-action -- --last --adapter slack

# Curtain up — real CALL-E (operator only)
# Key: https://dashboard.heycall-e.com/account/api-keys
# cp .env.example .env  → CALLE_API_KEY + CS_OWNER_E164
npm run signal -- --fixture stuck_support_acme.json --live PLACES

Exit codes: 0 ok · 2 HOLD · 3 failure. Action intents land in data/actions/pending/. Never commit .env.

Operator-proven live ladder

Real curtain-up calls against CALL-E — logged honestly, misses included.

  • stuck_support — voicemail → no_answer, then curtain-up → line reading 1 (take over in chat)
  • agent_needs_decision — earlier unclear captures, then curtain-up → line reading 1 (approve A)

Callee is always the CS owner. Customer never gets this call. Full probe table: research/calle-api-notes.md. Redacted rows: submission/evidence.