| name | call-mining |
| description | Step 2 of the ICP playbook. Mines each call transcript for the six required fields (Trigger, Incumbent, Pain language, Buyer profile, Features, Company shape) and writes one markdown file per call. Use after Step 1 (calls pulled) when the user wants per-call structured extractions, verbatim pain quotes, or a corpus that downstream steps can cluster from. |
Step 2 — Mine each call for six fields
What you produce
For every call in ./icp-output/calls-raw/ (or in memory from Step 1), produce one markdown file at ./icp-output/calls/<call-id>.md with the schema in templates/per-call.md.
Per-call detail saved separately is non-negotiable. Step 6 will pull from these files when packaging pockets — verbatim quotes, named accounts, named features. If you compress these into a summary now, you cannot recover the evidence later.
How to extract (the prompt)
For each transcript, run the following extraction prompt. Use a subagent (agents/call-miner.md) when call count > 30 — many calls in parallel is faster and avoids context bloat.
You are extracting structured ICP signals from a sales call transcript.
Output strict markdown matching the schema below. Do not invent any field.
If a field is not present in the transcript, write `unclear` — never guess.
Direct quotes must be verbatim, copied character-for-character from the transcript.
# Call: <call-id>
- date: <YYYY-MM-DD>
- account: <company name as stated>
- stage: <disco|demo|intro|negotiation|closed-won|closed-lost|stalled|no-decision>
- outcome: <won|lost|stalled|no-decision|open>
- duration_min: <number>
- recording_url: <url>
## Trigger
What concrete event brought this buyer to the call? Be specific:
"new CRO joined 6 weeks ago and is auditing the stack" beats "they want a sales tool".
If the transcript doesn't reveal a clear trigger, write "unclear — no compelling event surfaced".
## Incumbent
What tool or alternative are they using, leaving, or comparing? Include the verbatim mention.
Distinguish: current_tool / evaluating_alternatives / leaving_tool / building_in_house / nothing.
## Pain language (verbatim)
Three to seven direct quotes from the buyer that describe the pain. Each as a bullet.
No paraphrase. Only what the buyer actually said.
## Buyer profile
- title: <as stated>
- seniority: <IC | Manager | Senior Manager | Director | VP | C-level>
- function: <Sales | RevOps | Marketing | CS | Engineering | Product | Founder | Other>
- decision_role: <champion | decision-maker | economic-buyer | influencer | end-user | unclear>
## Features that resonated
Which specific features or capabilities did the buyer react positively to?
Use direct quotes where possible. Distinguish demo features from disco use-cases.
## Company shape
- industry: <as inferred from transcript or known>
- headcount: <range or stated>
- stage: <Seed | Series A | B | C | D | Public | Private | Bootstrapped | unclear>
- geography: <HQ region>
- growth_signals: <hiring spikes, recent funding, new exec hire, M&A — only if mentioned>
- tech_stack_mentioned: <CRM, sequencer, data warehouse, etc. — only if mentioned>
## Notes
Anything else relevant to ICP that doesn't fit the schema. Keep brief.
Speaker attribution gotchas
- "We" from a buyer = their company. "We" from a rep = your company. The transcript should attribute speakers; if it doesn't, your tool's docs will tell you how speaker IDs map.
- A pain quote attributed to the rep is useless. Always check who said it.
Volume strategy
| Call count | Strategy |
|---|
| < 30 | Sequentially, in this main agent |
| 30–150 | Parallel subagents in batches of ~10 calls each |
| 150–500 | Parallel subagents in batches of ~25 |
| 500+ | Two-phase: subagents extract, main agent does cross-call sanity sweeps |
When dispatching subagents, give each one a list of call IDs and the same extraction prompt above. Each subagent writes its own output files. The main agent does not need to see all extractions in context — it only needs the file paths for downstream steps.
Quality checks before moving to Step 3
After all extractions are written, sample-check 5 random files:
- Are pain quotes actually verbatim (no rewording)?
- Are titles concrete (not just "manager")?
- Is the trigger an event, not a generic want?
- No invented company names?
If any fail, re-extract those calls with a tightened prompt that quotes the failure mode.
State update
{
"step": "2",
"step_status": "completed",
"calls_extracted": <count>,
"extraction_quality_sample": "5/5 passed | 4/5 passed (re-ran 1)"
}