Skip to content

Instantly share code, notes, and snippets.

@mda590
Created April 4, 2026 12:18
Show Gist options
  • Select an option

  • Save mda590/ec441644dc2c43c336f69494a00b0c04 to your computer and use it in GitHub Desktop.

Select an option

Save mda590/ec441644dc2c43c336f69494a00b0c04 to your computer and use it in GitHub Desktop.

Slack Triage Agent — Bootstrap Prompt

Copy everything below this line and paste it into Claude Code on your work machine.


I want to build a Slack triage agent using Goose (https://block.github.io/goose/) with Claude Code as the provider. This is Phase 1 of a larger multi-agent system inspired by Paul Shortland's architecture (Temporal + Agent SDK + 3-tier recall). For now we're keeping it simple.

What to build

Create a project at ~/Projects/slack-triage-agent/ with this structure:

slack-triage-agent/
├── recipes/
│   ├── slack-triage.yaml
│   └── simulate-triage.yaml
├── context/
│   ├── team.md
│   ├── projects.md
│   └── triage-rules.md
├── logs/
│   └── (triage logs land here, one per day)
└── prompts/
    └── (for custom Goose prompt templates later)

Prerequisites

  1. Install Goose CLI: brew install block-goose-cli
  2. Verify: goose --version
  3. I have an Anthropic API key ready
  4. I have Claude Code CLI installed already

Recipe 1: slack-triage.yaml

A Goose recipe that:

  • Uses claude-code as the provider (settings.goose_provider: "claude-code")
  • Takes parameters: channels (required, comma-separated channel names), logs_dir (optional, default ./logs), date (optional, default today), lookback_hours (optional, default 24)
  • ALL parameters must be referenced in the instructions via {{ param_name }} Jinja2 syntax or Goose will error saying "Unnecessary parameter definitions"

The instructions should tell the agent to:

Step 1 — Load memory: Read all triage log files from {{ logs_dir }}/ from the past 7 days. Use them to recognize recurring issues, track open items from previous days, apply learned patterns, and reference specific previous triages.

Step 2 — Load context: Read all files in the context/ directory for org structure, project info, and triage rules.

Step 3 — Fetch messages: Fetch the last {{ lookback_hours }} hours of messages from channels: {{ channels }}. Use Slack MCP tools.

Step 4 — Classify each thread by priority:

  • URGENT: Production impact, outages, security incidents, customer-facing with no workaround. Action needed within 1 hour.
  • ACTION_NEEDED: Direct questions with no response after 2+ hours, requests with deadlines, blocking PRs. Action needed within 24 hours.
  • FYI: Announcements, resolved issues, automated reports, general discussion.
  • NOISE: Social chatter, bot noise, already-resolved, duplicates.
  • When in doubt, classify UP (FYI → ACTION_NEEDED, ACTION_NEEDED → URGENT).

Step 5 — Draft responses for URGENT and ACTION_NEEDED items (brief summary + suggested action + who it's relevant to).

Step 6 — Write daily log to {{ logs_dir }}/{{ date }}-triage.md with this structure:

# Triage Log — [DATE]

## Summary
- X messages triaged across Y channels
- N URGENT, N ACTION_NEEDED, N FYI, N NOISE

## URGENT
### #channel-name: Brief title
- **First reported**: time by @who
- **Context**: what happened
- **Suggested action**: what to do
- **Pattern note**: any connection to previous issues

## ACTION_NEEDED
(same format)

## FYI
(brief list)

## Open Items Carried Forward
(items from previous days still unresolved)

## Patterns & Learnings
(new observations from today's triage — the agent teaches its future self)
(build on patterns noted in previous days, don't repeat them)

The "Patterns & Learnings" section is critical — this is the agent's memory. Each run reads its own previous logs and accumulates observations.

Recipe 2: simulate-triage.yaml

A simulation recipe for testing triage rules against historical Slack messages (Paul's key technique — replay 30 days of history to refine rules before going live).

  • Provider: claude-code
  • Parameters: input_file (required, path to historical messages), output_file (optional, default ./logs/simulation-results.md)
  • Instructions: Read the input file, classify each message/thread using the same rules as the triage recipe, draft responses for URGENT/ACTION_NEEDED, write results to output file, and end with a self-assessment: which classifications are least confident and why, what additional context would help, what patterns emerge.
  • Also read context files from context/ directory.

Context files

context/team.md

Create with placeholder sections (commented out examples) for:

  • Org structure (my name, role, team)
  • Key people (names, roles, what to escalate to them)
  • Channels to watch (which channels, what traffic they get)

context/projects.md

Create with placeholder sections for:

  • Current priorities (active projects/initiatives)
  • Known issues (things the agent should recognize as existing/known)

context/triage-rules.md

Create with:

  • Priority definitions (URGENT, ACTION_NEEDED, FYI, NOISE) with concrete examples
  • Escalation rules section (starts mostly empty — gets refined through simulation)
  • Note that this file is a living document refined through simulation

Verify it works

After creating everything, run:

cd ~/Projects/slack-triage-agent
goose run --recipe recipes/slack-triage.yaml --explain
goose run --recipe recipes/simulate-triage.yaml --explain

Both should parse without errors. The first should show channels as a required parameter. The second should show input_file as required.

Architecture context (for your understanding, not to build now)

This is Phase 1 of a 3-tier memory system:

  • Tier 1 (now): Short-term recall via daily log files loaded into context. 7-10 days fit easily in Opus 4.6's 1M context.
  • Tier 2 (later): Long-term recall via ChromaDB + SQLite for semantic search over months of history, exposed as an MCP server.
  • Tier 3 (now): Curated recall via the context/ files — hand-maintained org knowledge.

Future phases will add: safety-wrapped CLI MCP servers, dynamic prompt assembly, Temporal for durable execution, and running in Kubernetes via CronJob with the official Goose Docker image (ghcr.io/block/goose:latest).

How to run the simulation (my next step after setup)

# Export some Slack messages to a markdown file, then:
goose run --recipe recipes/simulate-triage.yaml \
  --provider claude-code \
  --params input_file=./sample-slack-messages.md

How to schedule daily triage (after simulation proves the rules)

goose schedule add --schedule-id morning-triage \
  --cron "0 0 9 * * *" \
  --recipe-source ./recipes/slack-triage.yaml
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment