Skip to content

ROLE: Product Manager ​

examples/25-role-product-manager.halo policies |! people

Ingest feature requests, cluster them by theme, score against strategy, and draft a roadmap brief

Open in the playground →

halo
// ============================================================
// ROLE: Product Manager
// PURPOSE: Ingest feature requests, cluster them by theme,
//          score against strategy, and draft a roadmap brief
// ============================================================

policy BudgetPolicy    : MaxSpend(1.00)
policy StrategyAlign   : Enforce(ProductStrategy.JSON)

// --- Tools ---
tool Linear          : POST("api.linear.app/graphql", apiKey: Env.LINEAR_KEY)
tool Notion          : POST("api.notion.com/v1/pages", apiKey: Env.NOTION_KEY)
tool SlackPM         : POST("hooks.slack.com/services/pm-team")

// --- Store ---
tool RequestHistory  : VectorStore(Env.PINECONE_KEY, namespace: "feature-requests")
tool ProductDocs     : VectorStore(Env.PINECONE_KEY, namespace: "product-strategy")

// --- Agents ---
agent Clustering [openai/gpt-4o-mini, temp: 0.2]
  system """
    You are a feature request analyst. Cluster raw user
    requests into coherent themes by user segment, problem
    area, and urgency. Deduplicate and normalize language.
  """
  requires BudgetPolicy

agent Strategist [anthropic/claude-sonnet-4, temp: 0.3]
  system """
    You are a product strategist. Score feature clusters
    against strategic goals using a weighted matrix. Prioritize
    by revenue impact, retention lift, competitive edge, and
    engineering effort. Output ranked recommendations.
  """
  equips ProductDocs
  requires StrategyAlign, BudgetPolicy

agent Writer [openai/gpt-4o-mini, temp: 0.5]
  system """
    You are a product communications writer. Draft roadmap
    briefings with strategic narrative arc. Lead with the
    "why now," follow with prioritized themes, close with
    resource asks and timeline.
  """
  equips Notion

// --- The Pipeline ---
@timeout(10m)
pipeline RoadmapBrief(requests: FeatureRequests) -> Briefing:
  requests
    // Step 1: Cluster raw requests into themes
    |> Clustering.cluster(
         context.data.requests.items,
         ["user_segment", "problem_area", "urgency"],
         8
       ) as clusters

    // Step 2: Gate — need at least 3 items to be actionable
    |? (context.data.clusters.total_items > 3)

    // Step 3: Score each cluster against strategic goals
    |> Strategist.score(
         context.data.clusters.themes,
         ProductDocs,
         ["revenue_impact", "retention", "competitive_edge", "effort"]
       ) as scoring

    // Step 4: Gate — drop clusters below threshold
    |? (context.data.scoring.top_scores > 50)

    // Step 5: Draft the roadmap brief, then save it to Notion
    |> Writer.compose(
         "RoadmapBrief",
         [context.data.clusters, context.data.scoring.ranked],
         "strategic_narrative"
       ) as draft
    |> Notion.create_page(
         title: "Roadmap Brief",
         content: context.data.draft
       ) as notion

    // Step 6: Send draft to PM Slack for feedback
    |! yield(
         SlackPM,
         context.data.draft.executive_summary,
         [context.data.notion.doc_url],
         24h
       )

    // Step 7: Wait for PM review
    ~> listen(SlackPM.Reaction) as pm_review

    // Step 8: Gate on approval
    |? (context.data.pm_review.status == "approved")
    |> System.Publish(
         context.data.notion.doc_id,
         "product-team"
       )

curl -fsSL https://halolang.com/install.sh | sh