Daily Overview Slack Posting ā Architecture
Flow (Step by Step)
Trigger
The daily overview is generated by Claude Code, triggered by .github/workflows/daily-overview.yml:
- Schedule: Cron at midnight UTC daily (
0 0 * * *) - Manual:
workflow_dispatchwith optionaltarget_datefor retrospective runs
Execution Chain
Plan Steps (from .github/prompts/daily-overview.md)
| Step | Name | Purpose |
|---|---|---|
| 1 | pull-history | Fetch PRs + commits for 24h window |
| 2 | classify-changes | Categorize by user impact |
| 3 | segment-summary | Split into Product/Engineering buckets |
| 4 | draft-details | Write detailed sections below --- divider |
| 5 | craft-compact | Write COMPACT block (TL;DR, highlights, wins, slowdowns) |
| 6 | craft-head | Write HEAD block (punchy 4-6 bullet headline) |
| 7 | commit-and-pr | Commit, push, create non-draft PR with labels |
Slack posting is not in the plan ā it happens in a separate GitHub Action triggered by the PR.
File Structure
<!-- HEAD_START -->
š Product Update ā Jan 28
⢠š± iPad onboarding works ā more completions
⢠š„ Large videos fail less ā smoother delivery
⢠š Admin visibility up ā faster support
<!-- HEAD_END -->
<!-- COMPACT_START -->
### š§ TL;DR
...
<!-- COMPACT_END -->
---
### ā Details ā
...
Posting Logic
The posting script (post-daily-overview-to-slack.ts) extracts the HEAD and COMPACT blocks:
- HEAD + COMPACT present +
SLACK_BOT_TOKENset: Posts HEAD as main channel message via Slack Web API, COMPACT as threaded reply usingthread_ts - HEAD + COMPACT present, no token: Falls back to combined webhook message (no threading)
- Only COMPACT or raw content: Posts via webhook as single message
Threading Mechanism
| Method | Auth | Threading | When Used |
|---|---|---|---|
| Incoming Webhook | None (URL has token baked in) | Not supported | Fallback when SLACK_BOT_TOKEN not set |
Web API chat.postMessage | SLACK_BOT_TOKEN env var | Supported via thread_ts | Primary path (GHA has the secret) |
GitHub Action Workflows
| Workflow | Trigger | Purpose |
|---|---|---|
daily-overview.yml | Cron (midnight UTC) / manual | Runs Claude Code to generate the overview |
daily-overview-post.yml | pull_request: opened (path: .kanbn/daily-overview/*-daily-overview.md) | Posts to Slack with SLACK_BOT_TOKEN from secrets |
auto-merge-eligible.yml | pull_request: opened (path: .kanbn/**/*.md) | Adds auto-merge label if PR only changes safe markdown files |
Key Files
| File | Role |
|---|---|
.github/workflows/daily-overview.yml | Cron trigger, runs Claude Code via claude-code-action@v1 |
.github/workflows/daily-overview-post.yml | PR-triggered Slack posting |
.github/workflows/auto-merge-eligible.yml | PR-triggered auto-merge label check |
.github/prompts/daily-overview.md | 7-step plan Claude Code follows |
.kanbn/daily-overview/daily-overview-template.md | Template with HEAD + COMPACT + Details structure |
packages/ci-scripts/src/find-daily-overview-file.ts | Finds the overview file from PR changed files |
packages/ci-scripts/src/post-daily-overview-to-slack.ts | CLI script: extracts HEAD/COMPACT, dispatches posting |
packages/ci-scripts/src/utils/post-markdown-to-slack.ts | Posting logic: webhook + Web API threading |
packages/ci-scripts/src/convert-markdown-to-slack.ts | Markdown ā Slack mrkdwn conversion |
packages/ci-scripts/src/check-auto-merge-eligibility.ts | Checks if PR is safe to auto-merge |
Design Decision: Why Slack Posting Lives in a GHA Workflow
Claude Code generates the daily overview markdown and creates a PR. Slack posting happens in a separate GitHub Action (daily-overview-post.yml) triggered by the PR, not inside Claude Code.
Why? Content generation is decoupled from delivery. The SLACK_BOT_TOKEN is only needed in the posting workflow, keeping the generation step focused on analysis and writing. This also means:
- Content generation (Claude Code) is decoupled from delivery (GHA)
- Posting is deterministic ā same script, same secret source, every time
- The plan is simpler (7 steps instead of 8)
Migration History
This system was originally implemented using the Cursor cloud agent API (POST /v0/agents). It was migrated to anthropics/claude-code-action@v1 for:
- Simpler architecture: Claude Code runs directly in the GHA runner with full repo access ā no remote agent launch, no model selection API calls, no agent monitoring
- Reliability: No dependency on Cursor API availability or model availability
- Unified tooling: Same Claude Code that developers use locally