For end users
weekly-analysis
Two-step weekly analysis that interprets your data first, then ranks five article ideas.
What it does
Lives in Content Insights → Insights as two buttons:
- Analyze now (Stage 1). Auto-refreshes GA4 + Search Console if their last fetch was over 24 hours ago, snapshots your data, then asks Opus to interpret it. Pulls brand voice, ICP, knowledge insights, top keywords with GSC numbers, recent articles, answer-the-public seeds, plus the new analytics tables: GA4 last 30 days (overall daily + top 50 pages + top 20 source/medium) and Search Console last 14 days (impression-weighted week-over-week query deltas, top risers + decliners). Returns a structured interpretation: weekly summary, traffic source mix, top-performing pages with conversion rate, declining pages with refresh actions, weekly query movers, rising keywords, keyword clusters, suggested new categories, and negatives.
- Recommend posts (Stage 2). Reads the latest interpretation and asks Opus to rank exactly five post suggestions, each with title, angle, primary + supporting keywords, target persona, content type, projected monthly traffic, and a rationale that references the Stage 1 findings by name (e.g. “defends top-performing page X” or “chases riser Y”).
Splitting the two means the interpretation is reusable. Click Recommend (or Renew, which excludes prior titles) multiple times against the same Analyze run and get different idea passes without re-paying for Stage 1’s interpretation tokens.
Inputs (Stage 1)
project_idand resolvedbrand_idbrand_profile(voice, tonality, guidelines)icp_profile(personas, painpoints, notes)analytics_metricssource=ga4 (last 30 days)gsc_daily(last 14 days, for week-over-week query deltas)keywordswith their GSC aggregates fromkeywords.metadataarticles(title, category, date, word count)answer_public_entriesgrouped by seed keywordproject_data_freshness(so the prompt can flag stale data)
Outputs
Stage 1 lands in data_interpretations.interpretation (jsonb): summary, traffic_source_mix, weekly_query_movers, top_performing_pages, declining_pages, rising_keywords, old_posts_rising, keyword_clusters, suggested_new_categories, suggested_negatives. The new GA4 / GSC-derived sections are optional — they’re omitted when no data exists rather than fabricated.
Stage 2 lands in idea_generations.ideas (jsonb): post_suggestions (exactly 5) and suggested_articles_by_traffic (up to 8).
Contract
The product contract Stage 2 enforces:
- Always returns 5 suggestions. Never zero, never a partial batch. The prompt has an explicit “Always return 5. Never zero.” clause; the schema requires
min(5).max(5). - Never duplicates published articles. Hard constraint in the prompt: “do not suggest topics the reader has already written. The EXISTING ARTICLES section above is everything they’ve already published. If your suggestion’s working title or primary keyword closely matches any existing article title, drop it and pick a different angle.” The reader’s job is to fill gaps, not duplicate work.
- Renew gives different angles. The Renew button re-runs Stage 2 with the prior generation’s titles excluded from the prompt, so a second pass produces five genuinely different angles rather than rewordings.
Fail-soft flow
Stage 1 is fail-soft at the action layer. If structuredCall throws (schema validation, API error, anything), a placeholder interpretation row saves with status='done' and a synthesized summary explaining what went wrong. Recommend can still run against the placeholder row. The user always reaches 5 post suggestions even when the interpretation flakes. The interpretation flakiness shows up in the SummaryBox as a degraded-but-honest “Stage 1 had trouble reading the data this run, click Re-analyze to retry” message, not as a hard error blocking the page.
When to run
Whenever your data has moved. The auto-refresh in Analyze means you can click Analyze once a week, once a day, or after a big content push without remembering to refresh the inbound apps first. Recommend is cheap relative to Analyze (no fetch, no interpretation re-pay) so re-running it for a different five angles is the lighter loop.
The skill is the heaviest single call in Pectus, so the runner uses prompt caching on the stable layers (brand, ICP, knowledge) to keep cost down across reruns within the same window.
Where it lives
cms/src/lib/insights/actions.ts (server actions: runAnalyzeOnly, runRecommendOnly, renewIdeas). The Stage 1 prompt builds against the gatherers at cms/src/lib/insights/gather-ga4.ts and cms/src/lib/insights/gather-gsc-daily.ts.