Gong 独自の週次サマリーメールと比較して。 Gong のサマリーはコールのみです。冷え込みシグナルを多く運ぶメールと CRM のアクティビティを見逃します。またクオリフィケーションフレームワークを適用しないため、「Economic Buyer が指名されていないため行き詰まっている」を浮かび上がらせることができません。有用な補完であり、代替品ではありません。
ステージ変化をシグナルとして使うと嘘をつく場合があります。 Closed Lost に案件を移動した担当者はステージ変化として表示されますが、ヒーティングを促進すべきではありません。ガード:バケット化ルールはステージのロールバックと Closed Lost の遷移をクーリングの下で明示的に扱い、ヒーティングには決して入れません。
---
name: activity-summarizer
description: Summarize one rep's last seven days of Salesforce activity, Gong calls, and email touches into a six-bullet signal report — what is heating up, what is cooling, where the rep is stuck, one suggestion. Designed for Friday self-review, not surveillance.
---
# Activity summarizer
## When to invoke
Use this skill on Friday (or any chosen weekly cadence) for a single rep's pipeline. Inputs are a Salesforce user ID and a seven-day window; output is a Markdown signal report scoped to that rep's open opportunities. The brief is rep-facing first and lands in the rep's DM, not the manager channel.
Do NOT invoke this skill for:
- Cross-team pipeline reviews (use a dashboard, not a Skill — N reps means N invocations and the cost compounds)
- Manager surveillance ("show me what Bob did this week") — privacy posture is broken if the rep didn't run it themselves
- Account-level deep dives (use the `account-research` skill instead)
- Forecast-call prep where you need numeric roll-up (Salesforce reports do this better and cheaper)
- Windows shorter than three days — too few datapoints for the rubric to fire cleanly
## Inputs
- Required: `rep_user_id` — Salesforce user ID (not the email; the API treats them differently)
- Required: `window_days` — integer, defaults to 7. Skill rejects values < 3 or > 28
- Optional: `framework` — one of `meddpicc`, `bant`, `custom`. Defaults to `meddpicc`. If `custom`, the skill loads `references/qualification-framework.md` and uses that as the lens
- Optional: `recipient` — `dm` (default) or `email`. Manager auto-cc is intentionally not an option
- Optional: `min_call_duration_seconds` — defaults to 300 (filters Gong noise; see watch-outs)
## Reference files
The skill loads these from `references/` on every run. Replace template contents with your team's actuals before first production use — the skill works without edits but the output reads generic.
- `references/qualification-framework.md` — the rubric the skill uses to decide "where is the deal stuck." Defaults to a MEDDPICC scaffold; swap in your team's variant
- `references/signal-rubric.md` — the thresholds the skill uses to bucket activity as heating / cooling / stuck. Has knobs for what counts as a "meaningful touch" and what triggers a "stuck" flag
- `references/sample-output.md` — a worked example the skill conditions on for tone, length, and formatting. Edit this when you want to nudge the voice (e.g. blunter, less hedged)
## Method
The four sub-tasks run in order. Steps 1 and 2 fetch in parallel; steps 3 and 4 are strictly sequential because ranking depends on synthesis.
### 1. Pull activity streams
Run two API calls in parallel:
- **Salesforce**: SOQL for `Task` and `Event` records where `OwnerId = rep_user_id` and `ActivityDate` within the window, plus `OpportunityHistory` rows for stage changes on opportunities owned by the rep. Filter Tasks where `Type IN ('Email', 'Call', 'Meeting')` — drop "Logged Call" with empty `Description` (these are usually CRM hygiene noise, not engagement)
- **Gong**: `/v2/calls` filtered by `participants.userId = rep_email` (Gong indexes by email, not Salesforce user ID — translate first), within the window. For each call, pull `summary`, `talkRatio`, `nextSteps`, and `flaggedQuestions` from `/v2/calls/{id}/extensive`. Drop calls where `duration < min_call_duration_seconds` — short calls are usually voicemails or test calls and produce noisy signals
If a stream fails, continue with the other and tag the report header `[Salesforce unavailable]` or `[Gong unavailable]`. Never silently produce a partial report — the rep must know what's missing.
### 2. Join to opportunity context
For each open opportunity owned by the rep, build a record with: stage, amount, close date, last stage change, count of activities in window, count of calls in window, and the qualification framework's required fields (e.g. for MEDDPICC: Metrics, Economic buyer, Decision criteria, etc.). Pull the framework field names from `references/qualification-framework.md` — do not hardcode field names in the skill.
### 3. Bucket per opportunity
For each opportunity, apply the signal rubric (see `references/signal-rubric.md`):
- **Heating**: stage advanced this week OR ≥ 2 multi-threaded touches OR a flagged buying-question on a call
- **Cooling**: no rep-side touch in ≥ 10 days AND last prospect reply > 14 days OR stage rolled back
- **Stuck**: open in current stage > 1.5x the team's median time-in-stage AND framework field gap (e.g. no Economic Buyer named)
A deal can only sit in one bucket. Order of precedence: Cooling > Stuck > Heating. This prevents the "heating but actually broken" false positive that surfaces when stage advanced for procedural reasons but signal is otherwise dead.
### 4. Rank and render
Pick the top three Heating, top two Stuck (or Cooling, if no Stuck), and produce one suggestion. The suggestion must name a specific deal, a specific stage, and a specific blocker — never a generic "follow up with stale leads" line. If the rubric cannot produce a deal-specific suggestion (e.g. all deals are healthy), the skill writes "No suggestion this week — pipeline is clean" rather than padding.
Render to the format below and ship.
## Output format
```markdown
# Week of {YYYY-MM-DD} — {Rep first name}
## Heating
1. **{Account}** — {one-sentence what changed}. Signal: {citation, e.g. "Gong call 2026-04-29: economic buyer joined, asked about pricing tiers"}
2. **{Account}** — ...
3. **{Account}** — ...
## Stuck
1. **{Account}** — {one-sentence what is blocked}. In {stage} for {N} days (team median: {M}). Missing: {framework field, e.g. "no Economic Buyer named"}
2. **{Account}** — ...
## Suggestion for next week
{Single specific action tied to a named deal and a named stage}. e.g. "On Acme, you have a technical evaluator but no Economic Buyer; propose a 30-min exec brief with their CFO."
## Sources
- Salesforce activities: {N} tasks, {M} events, {K} stage changes
- Gong calls: {N} (filtered {dropped} below {threshold}s)
- Window: {start} → {end}
```
## Watch-outs
- **Privacy posture: rep-facing only.** Default `recipient` is `dm` and the skill refuses to send to a manager channel. If a manager wants visibility, the rep forwards. Auto-cc would change the social contract from "weekly self-review" to "weekly snitch report" — and reps would game the input data within a week
- **Gong transcript quality.** International calls and bad audio produce noisy summaries that feed bad signals. Guard: `min_call_duration_seconds = 300` filters voicemails and test calls; the skill also reads Gong's per-call `transcriptionConfidence` field and drops anything below 0.6
- **Activity definition drift.** "Logged Email" with no body and no reply is not engagement; it's CRM hygiene theater. Guard: the SOQL filter requires non-empty `Description` on Tasks and ignores Tasks where `Subject` matches the team's auto-logged patterns (`/^(Email\: |Logged via )/`)
- **Suggestion fatigue.** The "one suggestion" line drifts toward generic ("follow up with stale leads") when the rubric is loose. Guard: the rendering step rejects any suggestion that does not name an Account, a Stage, and a specific Blocker. If the rubric cannot produce one, the skill writes "No suggestion this week" rather than fabricating
- **Token cost compounds with rep count.** A single weekly run is ~6k input + ~800 output tokens (~$0.05 on Sonnet). Twenty reps × four weeks = ~$4/month, fine. Two hundred reps × daily = ~$280/month, no longer cheap; switch to Haiku or batch
- **Stage-changes-as-signal can lie.** A rep moving a deal to "Closed Lost" shows up as a stage change but should not feed Heating. Guard: bucketing rules treat stage rollbacks and Closed-Lost transitions explicitly under Cooling, never Heating
# Qualification framework — TEMPLATE (MEDDPICC default)
> Replace this template's contents with your team's actual qualification
> framework. The activity-summarizer skill reads this file on every run
> to decide which Salesforce fields signal a "stuck" deal. Without your
> real field names, the skill defaults to a MEDDPICC scaffold that may
> not match your CRM schema.
## Framework name
MEDDPICC (replace with `BANT`, `SPICED`, your team's homegrown variant, etc.)
## Required fields
For each letter / criterion, list the Salesforce field that holds it. The skill checks these fields per opportunity; missing values feed the "stuck" bucket via the signal rubric.
| Criterion | Salesforce field | What "filled" looks like |
|---|---|---|
| Metrics | `Opportunity.Metrics__c` | A quantified business outcome the buyer cares about |
| Economic buyer | `Opportunity.Economic_Buyer__c` | Named individual with budget authority — not the champion |
| Decision criteria | `Opportunity.Decision_Criteria__c` | Written list of how the buyer will choose |
| Decision process | `Opportunity.Decision_Process__c` | Sequence of meetings/approvals required to close |
| Paper process | `Opportunity.Paper_Process__c` | Procurement, security review, legal — sequenced |
| Identified pain | `Opportunity.Identified_Pain__c` | The pain in the buyer's words, not the rep's |
| Champion | `Opportunity.Champion__c` | Named individual who sells internally on the rep's behalf |
| Competition | `Opportunity.Competitors__c` | Named competitors in the deal, including "do nothing" |
## Stage-by-stage minimums
Per stage, which fields MUST be filled before the deal is allowed to advance. The skill flags any deal that has advanced past the minimum without the fields.
| Stage | Required fields |
|---|---|
| Discovery | Identified pain, Champion |
| Qualification | + Economic buyer, Metrics |
| Proposal | + Decision criteria, Decision process |
| Negotiation | + Paper process, Competition |
| Closed Won/Lost | (no further requirements) |
## Time-in-stage medians (for "stuck" detection)
Replace these with your team's actuals from a Salesforce report. The skill flags a deal as stuck when time-in-stage exceeds 1.5x the median below AND a required field for that stage is empty.
| Stage | Median days |
|---|---|
| Discovery | 14 |
| Qualification | 21 |
| Proposal | 14 |
| Negotiation | 10 |
## Disqualifiers
Single conditions that drop a deal out of the active pipeline regardless of field completeness. The skill surfaces these prominently in the report.
- No champion identified after 30 days in pipeline
- Economic buyer never met after Proposal stage entered
- Competitor named is one we historically lose to (list here): {Competitor 1}, {Competitor 2}
## Last edited
{YYYY-MM-DD}
# Sample output — TEMPLATE
> Replace the example below with one or two of your team's best
> historical reports (anonymized). The activity-summarizer skill
> conditions on this file for tone, length, and formatting. Edit
> when you want to nudge the voice — blunter, less hedged, shorter
> bullets, etc.
## Tone calibration notes
- Bullets are one sentence. If you need two sentences, the bullet is doing too much.
- Cite the source inline. "Gong call 2026-04-29" beats "according to recent activity."
- The suggestion line names a person if possible: "propose a 30-min exec brief with their CFO" beats "engage the executive sponsor."
- Avoid hedging adverbs: `seems`, `appears`, `potentially`. The skill has the data; either say it or don't include the bullet.
## Example
```markdown
# Week of 2026-04-26 — Sam
## Heating
1. **Acme Robotics** — moved to Proposal after technical evaluator
joined the demo. Signal: Gong call 2026-04-29, CTO asked about
SAML rollout timeline and pricing for 200 seats.
2. **Northwind Health** — champion forwarded the security questionnaire
without prompting. Signal: inbound email 2026-04-30 from
j.lee@northwind.example with attached SIG Lite.
3. **Globex Logistics** — second meeting set with Director of Ops
joining. Signal: Calendar event 2026-05-02, three external
attendees (champion + two new contacts).
## Stuck
1. **Initech Corp** — in Qualification for 38 days (team median: 21).
Missing: Economic Buyer field empty. Champion (Marcus, Ops Lead)
has not been able to surface budget owner.
2. **Stark Industries** — in Negotiation for 22 days (team median: 10).
Missing: Paper Process — procurement timeline never mapped.
## Suggestion for next week
On Initech, ask Marcus directly in Monday's sync: "Who signs off on a
$50k Ops tooling spend this fiscal year?" If he can't name the person,
escalate to a paid pilot path that bypasses procurement.
## Sources
- Salesforce activities: 47 tasks, 12 events, 4 stage changes
- Gong calls: 9 (filtered 3 below 300s)
- Window: 2026-04-26 → 2026-05-02
```
## What a bad sample looks like (for contrast)
The skill should NEVER produce output like this — keep this in the reference file as a negative example so the model conditions away from it:
```markdown
# Weekly Update
## Things That Are Going Well
- Several deals appear to be progressing
- The rep was active across multiple accounts this week
- Engagement seems strong
## Areas of Focus
- Some deals could use attention
- Consider following up with stale leads
## Suggestion
Continue the great work and keep the momentum going!
```
Failure modes shown above: vague accounts ("several"), hedging ("appears", "seems"), generic suggestion ("keep the momentum"), no citations, no specifics. The signal rubric and rendering guards in the skill exist to refuse output like this.
## Last edited
{YYYY-MM-DD}
# Signal rubric — TEMPLATE
> Replace this template's contents with your team's actual thresholds.
> The activity-summarizer skill uses these to bucket each opportunity
> as Heating, Cooling, or Stuck. Defaults below are sane starting
> points; tune after a few weeks of running the skill against your
> historical data.
## What counts as a "meaningful touch"
Not all activities are signal. The skill counts a Task or Event as a meaningful touch only if it meets one of the conditions below. Edit this list to match your CRM hygiene reality.
- Outbound call with a logged disposition AND non-empty `Description`
- Inbound or outbound email where the prospect replied within 7 days
- Meeting (Event type) with at least one external attendee
- Gong call ≥ {min_call_duration_seconds, default 300} seconds with `transcriptionConfidence` ≥ 0.6
Explicitly does NOT count:
- "Logged Email" entries with empty `Description` (auto-logged hygiene)
- Tasks with `Subject` matching `/^(Email\: |Logged via )/`
- Calendar invites without a confirmed external acceptance
- One-way LinkedIn messages without a reply
## Heating thresholds
A deal is Heating if ANY of:
- **Stage advancement**: `OpportunityHistory.StageName` moved forward this window AND the new stage's required framework fields are filled
- **Multi-threading**: ≥ 2 distinct external participants on calls / meetings this window (counts new contacts joining, not the same champion repeated)
- **Buying questions**: a Gong call this window contains a question flagged in Gong's `flaggedQuestions` field tagged as `pricing` / `timeline` / `procurement`
- **Champion proactivity**: champion sent ≥ 1 inbound email this window without rep prompting (detect via `Task.WhoId = champion AND Task.CreatedById = rep`)
## Cooling thresholds
A deal is Cooling if ALL of:
- No rep-side meaningful touch in ≥ 10 days
- Last prospect reply > 14 days ago
- OR `OpportunityHistory.StageName` rolled backward this window
- OR stage transitioned to `Closed Lost` (always Cooling, never Heating)
## Stuck thresholds
A deal is Stuck if BOTH of:
- Time in current stage > 1.5x team median for that stage (see qualification-framework.md for medians)
- At least one required framework field for the current stage is empty
## Bucket precedence
A deal can sit in only one bucket per week. If it qualifies for multiple, the skill applies this precedence (highest wins):
1. Cooling — if cooling, the heating signals are noise; surface the cooling
2. Stuck — if stuck and not cooling, surface the structural problem
3. Heating — only if neither cooling nor stuck
This precedence prevents the "stage advanced for procedural reasons but the deal is actually broken" false positive.
## Suggestion guardrails
The "one suggestion for next week" line at the end of the report MUST:
- Name a specific account (no "follow up with stale leads")
- Name a specific stage (no "move things forward")
- Name a specific blocker pulled from the qualification framework gaps
If the rubric cannot produce a suggestion meeting all three constraints, the skill writes "No suggestion this week — pipeline is clean" rather than fabricating one.
## Last edited
{YYYY-MM-DD}