| name | opportunity-discovery |
| description | Specialist tool that implements the lift_per_effort formula. Surfaces 5-15 ranked opportunities per week. Biases toward 90/10 plays (striking-distance, ctr-rescue, schema-fix, link-injection, cannibalization-consolidation, template-extension, linkable-asset). Used exclusively by Stage 1 Discovery. |
| metadata | {"family":"ops","owner":"seo","last_reviewed":"2026-04-29T00:00:00.000Z","version":"1.0.0","related_skills":["seo-foundations","marketing-foundations","traffic-monitor","seo-health","indexation-monitor"],"kpis":["Median lift_per_effort of approved briefs > p75 of all candidates","Discovery → Strategy approval rate 30-50% via Slack gate","5-15 candidates surfaced per week"],"marketing_pillar":124,"seo_standard":"B_C","kpi_tier":12,"funnel_stage":"all","content_class":"all","maturity_stage":"predictive","used_by_stages":[1]} |
Opportunity Discovery
Implements the lift_per_effort formula from .agents/agents/PIPELINE.md. Surfaces 5-15 ranked opportunities per week with 90/10 filter applied.
When to Use
- Stage 1 Discovery only — exclusive consumer.
Do Not Use When
- Need raw KPI data — use
traffic-monitor.
- Need cannibalization detection — use
seo-health.
- Need indexation status per pillar — use
indexation-monitor.
Inputs
- Cached
traffic-monitor output (Tier 1+2 metrics per pillar).
- Cached
seo-health output (cannibalization, anchor diversity, schema validity, pSEO uniqueness, intent-mismatch findings).
- Cached
indexation-monitor output.
user-semrush keyword-gap report (monthly).
- Content-class current 4-week mix (from prior weekly reports).
The lift_per_effort Formula
Per .agents/agents/PIPELINE.md:
lift_per_effort = (delta_impressions * delta_CTR * intent_value * confidence) / effort_hours
multiplied by content_class_boost:
informational: 1.1
brand: 1.2
transactional: 1.0
Coefficients live at marketing-foundations/reference/measurement-framework.md.
The 90/10 Class Taxonomy
Every opportunity tagged with one:
striking_distance — pages ranking 4-15 with impressions ≥100. CTR uplift dominates.
ctr_rescue — high impressions + CTR <2%.
schema_fix — already-ranking pages missing rich-result eligibility.
link_injection — orphans with audience but no incoming links.
cannibalization_consolidation — 2+ pages ranking for same primary query.
template_extension — extending an outperforming template.
linkable_asset — original-research pages.
other_with_text — requires text justification.
Workflow
- Pull cached evidence from
traffic-monitor, seo-health, indexation-monitor, last semrush keyword-gap.
- Generate candidate opportunities:
- For every page ranking 4-15 with impressions ≥100 →
striking_distance candidate.
- For every page with impressions ≥500 + CTR <2% →
ctr_rescue candidate.
- For every page failing schema validity →
schema_fix candidate.
- For every orphan page with GSC impressions ≥100 →
link_injection candidate.
- For every cannibalization finding →
cannibalization_consolidation candidate.
- For every outperforming template (CTR + engagement >p75 of peers) →
template_extension candidate.
- For every backlink-velocity gap (RDs/mo <10) →
linkable_asset candidate from data inventory.
- Score each candidate with
lift_per_effort formula.
- Apply content-class balance filter: reject candidates that worsen the 60/25/15 mix outside the acceptable band (per marketing-foundations/reference/content-class-balance.md).
- Apply capacity cap: max 15 candidates per week.
- Rank by
lift_per_effort × content_class_boost descending.
- Compute confidence per candidate (data freshness + sample size + similar-historical-prediction accuracy).
- Output the ranked opportunity table for Stage 1 Discovery to post as Slack selection gate.
Output Contract
Per opportunity record:
opportunity_id: <slug>-<YYYYMMDD>-<seq>
ninety_ten_class: striking_distance | ctr_rescue | schema_fix | link_injection | cannibalization_consolidation | template_extension | linkable_asset | other_with_text
target_url: <URL>
primary_query: <text>
current_position: <number>
target_position: <number>
current_impressions: <number>
current_ctr: <fraction>
delta_impressions: <number>
delta_ctr: <fraction>
intent: informational | navigational | commercial | transactional
intent_value: <coefficient>
content_class: informational | transactional | brand
content_class_boost: <coefficient>
effort_hours: <number, from baseline>
confidence: <0.0-1.0>
lift_per_effort: <computed>
evidence_links:
- <gsc-cache path>
- <ga4-cache path>
- <semrush-cache path>
Markdown summary in nextjs-app/docs/reports/<date>/01-discovery.md per PIPELINE.md Stage 1 contract.
Capacity Discipline
- Max 15 candidates per week (capacity).
- Discovery → Strategy approval rate target: 30-50% (i.e., 5-7 approved briefs from 15 candidates).
- If
lift_per_effort median < p50 of last 4 weeks, surface fewer (don't pad).
References