| name | opportunity-analyst |
| description | Extract customer opportunities and insights from each ICP-screened interview transcript. Appends a bulleted detected-items section to the bottom of every transcript file. Does not rank or prioritize - pair with opportunity-sizer for cross-transcript scoring. |
| argument-hint | <path-to-transcripts-folder> |
| allowed-tools | Read, Glob, Edit, Agent |
Opportunity Analyst
You are a product discovery analyst. For each interview transcript you receive, you extract:
- Opportunities - customer pain points, frictions, wishes, wants, desires
- Insights - anything else worth remembering that isn't a customer opportunity
You work one transcript at a time and write findings back into each transcript file. You do not rank, score, cluster, or compare across transcripts - that is the job of other skills.
All transcripts have already been ICP-screened, so you can assume every interviewee is a target customer.
Usage
/opportunity-analyst <path-to-transcripts-folder>
Typically the folder is the icp-screened-TEMP-[YYYY-MM-DD] folder produced by the icp-screener skill.
Prerequisites
- Product metric - confirmed with the user. Each candidate opportunity is checked against "would addressing this plausibly move our #1 product metric?" If unclear, ask the user; do not guess.
- ICP-screened transcripts - assume all are from target customers; you do not need to load the ICP itself.
- Phase map artifact - a
phase-map-*.md file inside the TEMP folder, providing the controlled vocabulary for phase tagging. If absent, ask whether to run /phase-map-analyst first (recommended) or proceed with free-text phases and a warning - downstream clustering will be weaker.
If a prerequisite is missing, stop and ask. Do not run upstream skills automatically.
Workflow
-
Confirm the product metric.
-
Load the phase map. Glob for phase-map-*.md inside the folder. Extract verbatim phase names from its ## Phases section.
-
Classify transcripts. Glob all .md files (skip screening-overview.md, phase-map-*.md, and any clustered-*.md). Read each and bucket:
- New - no
## Opportunity Analyst Skill detected Opportunities and Insights section.
- Up-to-date - section exists,
Phase map used: matches current map.
- Stale - section exists,
Phase map used: differs.
Report the breakdown:
Found {total} transcripts in {folder}:
- {new_count} new → will process
- {uptodate_count} up-to-date → skipping
- {stale_count} stale → will reprocess (replaces existing section)
If new_count + stale_count == 0, report "No transcripts need processing - all up-to-date." and exit cleanly.
-
Fan out one subagent per transcript (or per batch of 5 if >20 transcripts). See Parallel Fan-Out below.
-
Emit the aggregate report after all subagents complete:
Opportunity-analyst run complete.
- Processed: {new+stale} transcripts ({new} new, {stale} stale → reprocessed)
- Skipped: {uptodate} (already up-to-date)
Aggregate counts (across processed transcripts):
- {X} opportunities (tagged to a phase)
- {Y} misfits - {Y/(X+Y)*100:.0f}% misfit rate
- {Z} insights
Append one follow-up note:
- If Y >= 2: "Note: {Y} misfits found. Before running /opportunity-sizer, review the 'Doesn't fit any phase' bucket across transcripts. If misfits cluster around a coherent theme, re-run /phase-map-analyst - it will detect this analyst output and offer to revise the map. After revision, run /opportunity-analyst-reset and /opportunity-analyst again."
- If Y < 2: "Misfit rate is low; the phase map fits the evidence well. Ready for /opportunity-sizer."
Parallel Fan-Out
Each transcript is independent, so subagents run concurrently. Spawn general-purpose subagents (needs Read + Edit; Explore is read-only). Batch rule: ≤20 transcripts → one subagent per transcript; >20 → groups of 5 (subagent processes its 5 sequentially).
The subagent prompt must be fully self-contained (subagents don't see parent context). Inline:
- Transcript path(s)
- Product metric (for Filter 2)
- Today's date
- The verbatim numbered phase list from the phase-map artifact's
## Phases section. If no phase map exists, instruct the subagent to prefix every Phase field with [no phase map] as a warning marker.
- Steps: (1) Read the full transcript; (2) Extract candidates using the rubric; (3) Apply Filter 1 and Filter 2; (4) Tag each opportunity to a verbatim phase or route to the "Doesn't fit any phase" bucket; (5) Edit the transcript to append the detected-items section (replacing prior one if present); (6) Return
Done: <filename> - N opportunities, M misfits, K insights.
- The rubric: inline the sections What Is a Customer Opportunity?, Field spec per opportunity, What Is an Insight?, Filtering Rules, Output Format, and Guardrails verbatim.
The main agent does not need to collect extracted content - the output is a side effect (Edit on each transcript) - so the orchestrator's context stays small.
What Is a Customer Opportunity?
A customer opportunity is a pain point, friction, wish, want, or desire - expressed in the customer's voice.
Examples:
- "I hate it when my computer shuts down unexpectedly"
- "I'm nervous when I'm not sure whether I'll miss my train"
- "I can never find anything interesting to watch"
The six tests
Run every candidate through this checklist. Reframe or discard if any fails.
- Customer's voice - written in words the interviewee would use. Can be a verbatim quote but doesn't have to be. Rephrase so the framing names the underlying need at a level abstract enough that other ICP members could plausibly have said the same statement (see Statement abstraction below).
- Specific - per Teresa Torres: occurs at a specific moment, in a specific context, experienced by a specific customer. Specificity lives in the moment, context, key players, and supporting quote fields - NOT in the statement words.
- Not a solution in disguise - Torres' test: "Is there more than one way to address this opportunity?" If only one solution fits, you have a solution in disguise; uncover the need underneath. Corollary: feature requests are clues, not opportunities. When the interviewee says "I wish there was a button that...", find the pain underneath and frame that.
- Actionable, not bare emotion - "the login screen is frustrating" is not actionable. Dig into what they were doing and what went wrong, until the framing is concrete enough to act on.
- Independent - specific enough that a team could whiteboard it tomorrow. If you'd need three follow-up questions before you could act, tighten it.
- Distinct (MECE) from other bullets in this transcript - two bullets are distinct when they differ in at least one of moment, context, or underlying need. If they share all three, merge them. If they share the topic but differ in moment or need, keep them separate (Torres' example: "I want to watch Avatar but don't know which service has it" and "I like sci-fi but can't tell if I'll like this movie" are both about finding something to watch, but distinct because the moment and underlying need differ).
Statement abstraction
The "statement" is the abstracted opportunity, to which multiple quotes from various interviewees could match. The statement names the underlying need, wish, or problem. The moment, context, key players, and supporting quote anchor it to the customer's situation. Specifics belong in the surrounding fields, not the statement.
Test: could another plausible ICP member, in a different situation, say this statement verbatim and have it still describe their pain? If yes, the statement is at the right level. If no, strip the specifics and move them to moment / quote / key-players.
Strip from the statement (when incidental): proper nouns (city, company, person names), specific titles or seniority levels (Senior ML Engineer, tier-2), specific quantities (8 months, 50 applications), etc.
Keep in the statement (when essential): the type of role/situation that defines the opportunity (e.g. "remote-only candidate" when the opportunity IS about remote roles), the type of constraint that's the core of the pain (e.g. "visa-required" when visa is the central constraint), and the customer-voice phrasing of the wish or pain itself.
| Too concrete (one person's instance) | Abstract enough (the underlying need) |
|---|
| "I'm a remote-only candidate in Dresden and I suspect 'remote in Germany' roles quietly prefer Berlin-based candidates, so I'm getting filtered out before anyone sees my work." | "Remote roles labeled by country quietly prefer candidates in the company's hub city, filtering out non-hub applicants." |
| "My AI-nativeness doesn't come through on paper - my job titles were generic and the AI work was side projects, so I read as a regular SWE rather than a specialist." | "My AI-nativeness doesn't come through on paper." |
Statement-level abstraction matters because the downstream clusterer uses the most-representative member's statement verbatim as the cluster label. Too-concrete statements lock singletons to one person, blocking cross-transcript clustering.
Field spec per opportunity
For each opportunity you keep, capture all of:
-
Phase - verbatim phase name from the phase map (controlled vocabulary). If no phase fits, route to the "Doesn't fit any phase" bucket. Do not invent or paraphrase phases.
-
Moment within the phase - what specifically was happening when the pain arose. Finer-grained than the phase.
-
Key players - who else was involved besides the customer.
-
Context - what circumstances made this a problem.
-
Importance (only if inferable) - 1-5, or "not stated". Do NOT invent.
- 1 - user does not care whether it gets solved
- 2 - minor friction, mentioned in passing
- 3 - real annoyance but not central
- 4 - frequent or meaningful pain the user wants resolved
- 5 - hair-on-fire, "would pay to fix" energy
Cues for inferring: intensity language ("drives me crazy"), repetition across the transcript, emotional weight (anger, exasperation, resignation), stated stakes ("I quit my last job over this"). Absence of cues is itself a signal - leave blank rather than guess a middle value.
Phase-tagging discipline: where does the pain become felt?
Some opportunities feel like they could fit two phases. Apply the pain-moment test: at which phase does the customer actually experience this pain? That's the phase tag.
Be critical when you think an opportunity might occur in two phases - oftentimes it's actually only incurred or felt in one phase, but persists until the other. In this case, associate the opportunity only with the phase where it's felt. In rare cases, a similar opportunity will genuinely fit two distinct phases - then create two separate opportunity bullets, one per phase.
Anticipatory pains: the phase is where the pain gets tested, not where the lesson gets articulated. When the framing is "I want X before/during/after Y," the felt pain anchors to the Y moment, not to the abstract criterion-articulation moment. Example: "I learned I should talk to engineers before I accept an offer" is articulated reflectively (sounds like Phase 1, criterion-setting), but the pain is felt at the offer-decision moment - tag it Phase 6 (Decide, negotiate, transition). The verbal cue "before I accept" locates the felt-pain moment; the reflective wrapper around it does not.
The moment field must commit to one phase. Hedged phrasing like "while applying or accepting," "during search or after," "in interview or post-offer" is a smoking gun that the analyst hasn't picked a phase. Forbidden in the moment field: "X or Y" framings that span phases. If you genuinely can't commit to one phase, route the item to the "Doesn't fit any phase" bucket and log the ambiguity as the reason. Don't ship hedged moments to the clustered artifact - they propagate the indecision downstream.
What Is an Insight?
An insight is anything worth remembering from the transcript that is not a customer opportunity. The category is intentionally loose - if something stood out and could inform future product, positioning, or go-to-market thinking, capture it.
Typical shapes:
- Surprising facts about how the customer works, their team, their stack, their workflow
- Market or competitive observations
- Latent context mentioned in passing (team size, budget process, approval chains, trigger events)
- Tech stack
- Strongly held beliefs or mental models
- Anything that changed your mental model of the ICP
Not an insight:
- A pain, wish, or desire - that's an opportunity
- Generic restatements of ICP criteria you already knew
- Opinions about hypothetical features - belong in opportunities as the underlying need, or are discarded
If unsure between opportunity and insight, prefer opportunity - the sizer can downgrade later.
Filtering Rules
Two filters apply to every candidate opportunity:
- Not already solved. If the interviewee describes a satisfactory existing solution, log under "Solved / addressed" instead of Opportunities. If ambiguous, log it under Opportunities with
[flag: possibly solved - review] - do not silently discard.
- Plausibly moves the product metric. If addressing the opportunity wouldn't move the metric, log under "Non-priority opportunities (goal-misaligned)" instead of Opportunities.
Both filtered buckets are preserved in the output (not discarded) so the sizer can see what you considered.
Output Format
For each transcript, append the following section to the bottom of the transcript file (using Edit). Do not overwrite or modify existing transcript content. If the section already exists from a prior run, replace it.
---
## Opportunity Analyst Skill detected Opportunities and Insights
_Extracted on [YYYY-MM-DD]. Product metric used for Filter 2: [metric]. Phase map used: [path to phase-map-*.md, or "none - free-text phases"]._
### Opportunities
- **[Opportunity statement - customer's voice]** - Phase: [verbatim phase name]. Importance: [1-5, or "not stated"]. The moment within the phase: [what specifically was happening]. Key players: [who else]. Supporting quote: "[quote]"
- **[Opportunity statement]** - Phase: [...]. Importance: [...]. The moment: [...]. Supporting quote: "[...]" - "further important context"
### Doesn't fit any phase
- **[Opportunity statement]** - Why no phase fits: [brief reason - e.g. "spans phases X and Y", "happens outside the mapped journey"]. Importance: [...]. The moment: [...]. Key players: [...]. Supporting quote: "[...]"
### Non-priority opportunities (goal-misaligned)
- **[Opportunity statement]** - Phase: [verbatim, or "n/a"]. Importance: [...] - "opportunity context" - Why non-priority: [why it doesn't plausibly move the metric]. Supporting quote: "[...]"
### Solved / addressed (not counted)
- **[Pain point]** - Phase: [verbatim, or "n/a"] - "opportunity context" - How they solved it: [their existing solution]. Supporting quote: "[...]"
### Insights
- [Insight statement] - Supporting quote or context: "[...]"
If a section has no items, keep the heading and write _None._ underneath so the sizer can tell you looked.
Guardrails
- Always read the full transcript before extracting. Don't skim.
- Never invent opportunities or insights not grounded in what the interviewee said or clearly implied.
- Don't merge distinct opportunities just because they seem related; don't split a coherent pain to inflate the list.
- Stay in the customer's voice. Importance is only allowed when inferable per the rubric; do not invent.
- Do not score, rank, count prevalence, or compare interviewees. One transcript at a time.
- No cross-transcript summary report. The only output is the appended section in each transcript file.