From team-kanban
This skill should be used when the user says "team kanban", "update the team board", "post the kanban to Slack", "what's the team working on", "team task board", "sync the kanban", "team status board", "push tasks to Slack", "update #general board", "team kanban update", "kanban sync", or any request to aggregate tasks from multiple sources into a team-visible Slack kanban board. Also trigger when the user asks to "set up the team board", "create the team canvas", or references the #general kanban. This skill aggregates from Obsidian KANBAN_VIEW.md, Google Drive Active Tasks, Google Calendar, Gmail, Slack DMs/group DMs/threads, and project channels (#sams, #stig-viewer, #assured-book, #jtbd_analyzer, #team-edify, #cms-migration) — then posts to a persistent Slack Canvas and sends a daily digest message to #general.
How this skill is triggered — by the user, by Claude, or both
Slash command
/team-kanban:team-kanbanThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Aggregate tasks from the personal operations stack (Obsidian vault, Google Drive Active Tasks, Google Calendar, Gmail) and Slack conversations (DMs, group DMs, threads, and project channels: #sams, #stig-viewer, #assured-book, #jtbd_analyzer, #team-edify, #cms-migration) into a team-visible Slack Canvas kanban board with six columns. Post a daily formatted digest to #general. Support manual tea...
Aggregate tasks from the personal operations stack (Obsidian vault, Google Drive Active Tasks, Google Calendar, Gmail) and Slack conversations (DMs, group DMs, threads, and project channels: #sams, #stig-viewer, #assured-book, #jtbd_analyzer, #team-edify, #cms-migration) into a team-visible Slack Canvas kanban board with six columns. Post a daily formatted digest to #general. Support manual team input via Slack threads.
The following people can be assigned tasks. Use their short name in #assigned/ tags in Obsidian, or their Slack user ID for Canvas/message mentions.
| Name | Short Name | Slack ID | Role | |
|---|---|---|---|---|
| Dorian Cougias | dorian | U08PV3UHTEX | [email protected] | Founder/CEO |
| Philip Mudhir | phil | U096C551HBR | [email protected] | Core team |
| Steven P | steven | U098H0X9CQ4 | [email protected] | Core team |
| Michael Flanagan | michael | U09EB7N7B98 | [email protected] | Core team |
Contractors can be added with #assigned/firstname tags. If no Slack ID is known, display the name as plain text rather than a mention.
The board uses seven columns, ordered left to right:
| Column | Emoji | Purpose |
|---|---|---|
| Backlog | :inbox_tray: | Captured but not yet prioritized |
| P0 - Today | :fire: | Max 3 items. Time-sensitive, blocks other work, or external deadline within 24h |
| P1 - This Week | :star: | Max 7 items. Important but not today-urgent. Must move before Friday |
| Blocked | :no_entry: | Waiting on external input. Include who/what is blocking and how long |
| In Progress | :hammer_and_wrench: | Actively being worked on right now |
| In Review | :mag: | Task marked complete by the assignee — awaiting confirmation from the person who created or assigned the task before moving to Done |
| Done | :white_check_mark: | Confirmed complete. Clear weekly on Monday |
Triggers: "team kanban", "update the team board", "sync the kanban", "post the kanban", or the /team-kanban command.
Execute these steps in order:
Check if the current workspace folder contains KANBAN_VIEW.md in a Tasks/ directory. The vault is typically mounted at the Cowork workspace path. Set ${VAULT} to the resolved root.
If the vault is not mounted, use request_cowork_directory to ask Dorian to mount it.
Read ${VAULT}/Tasks/KANBAN_VIEW.md. Parse the Obsidian Kanban plugin format:
## :fire: P0 - Today (Max 3))- [ ] Task description #tags- [x] Task description#priority/p0, #cat/technical, #status/w (waiting), #project/sams#assigned/dorian, #assigned/phil, #assigned/steven, #assigned/michael, or #assigned/contractor-name#assigned/ tag default to Dorian (as the originator)Parse every task into a structured object:
{
title: "Task description",
column: "p0|p1|backlog|blocked|in-progress|in-review|done",
tags: ["tag1", "tag2"],
project: "project-name or null",
category: "technical|outreach|admin|marketing|leadership|strategy",
assigned_to: "short-name or dorian (default)",
assigned_slack_id: "U-prefixed Slack ID or null",
waiting_on: "person-name or null",
waiting_since: "date or null",
is_critical: boolean
}
IMPORTANT: The source (obsidian, slack, gmail, etc.) is internal metadata for deduplication only. NEVER display source tags on the Canvas or in digest messages. Tasks should show: title, project, assignee @-mention, and context — nothing else.
Assignee resolution: Look up the #assigned/ tag value against the Team Roster table. If the short name matches, populate both assigned_to and assigned_slack_id. If it's an unknown name (contractor), set assigned_to to the tag value and assigned_slack_id to null.
Slack thread assignments: When team members add tasks via #general thread replies, they can include an assignment:
P1 Review press release draft #reggenome @phil — assign to PhilP1 Fix login bug #sams — defaults to the person who posted it (look up their Slack ID in the roster)Fetch the Active Tasks document from Google Drive. The daily-ops plugin manages this document in the MoxyWolf Team Drive (driveId: 0AHxJ5CazJqxOUk9PVA), folder ID 1MjSabHDWYjjnp17DshdO9pnESLyvm6Gs.
google_drive_search with query name contains 'Daily Ops - Active Tasks'google_drive_fetch using the resolved document IDDeduplication: Compare task titles from Google Drive against Obsidian kanban tasks. Use fuzzy matching (title similarity > 80%). When duplicates are found, prefer the Obsidian version (it has richer tag metadata) but note the Google Drive source. Flag any tasks that exist in Google Drive but NOT in the Obsidian kanban — these may be items added via mobile or the daily-ops standup that haven't been synced to the vault yet.
Pull today's events using gcal_list_events:
source: calendar and the meeting timeUse gmail_search_messages with targeted queries:
is:inbox newer_than:1d (urgent OR deadline OR ASAP OR "action required")is:inbox newer_than:2d -from:me — then filter for emails explicitly requesting actionis:inbox newer_than:2d from:(phil OR mudhir OR strikegraph OR gryphon OR fortreum)subject:"Meeting summary" newer_than:2d — catch meeting recap emails regardless of sender. For each result, read the full message body with gmail_read_message and extract action items, deadlines, owners, and decisions. Match names mentioned in the summary against the Team Roster to assign tasks. Meeting summaries often contain the most concrete next-steps that don't surface in any other source.For each actionable email:
source: gmailUse slack_search_public_and_private to find action items buried in team conversations. This catches commitments, assignments, and to-dos that exist only in chat — the gap that daily-ops does NOT cover.
Search strategy — run these queries:
Group DMs with the team (last 48h):
after:[2-days-ago] in:<@U096C551HBR> (Phil group DMs)after:[2-days-ago] in:<@U09EB7N7B98> (Michael group DMs)after:[2-days-ago] in:<@U098H0X9CQ4> (Steven group DMs)channel_types: "mpim,im" to search DMs and group DMsDirect DMs between Dorian and each team member (last 48h):
from:<@U08PV3UHTEX> in:<@U096C551HBR> after:[2-days-ago] (Dorian→Phil)from:<@U08PV3UHTEX> in:<@U09EB7N7B98> after:[2-days-ago] (Dorian→Michael)from:<@U08PV3UHTEX> in:<@U098H0X9CQ4> after:[2-days-ago] (Dorian→Steven)Keyword-targeted searches (last 7 days):
"need to" OR "action item" OR "to do" OR "can you" OR "please" after:[7-days-ago] in DMs/group DMsProject channels (last 48h): Scan these project-specific channels for action items, decisions, and commitments:
after:[2-days-ago] in:#samsafter:[2-days-ago] in:#stig-viewerafter:[2-days-ago] in:#assured-bookafter:[2-days-ago] in:#jtbd_analyzerafter:[2-days-ago] in:#team-edifyafter:[2-days-ago] in:#cms-migrationFor each channel, extract:
Map channel to project tag automatically:
#sams → #project/sams#stig-viewer → #project/stigviewer#assured-book → #project/stigviewer (book content line)#jtbd_analyzer → #project/jtbd-analyzer#team-edify → #project/edify#cms-migration → #project/cms-migrationAction item extraction rules:
For each extracted action item, create a task entry:
{
title: "Extracted task description",
column: "p0|p1|backlog",
assigned_to: "person who committed or was assigned",
assigned_slack_id: "their Slack ID from roster",
context: "brief quote or summary of the conversation"
}
Note: Track the source internally for deduplication, but NEVER render source tags (like slack, obsidian, gmail) on the Canvas or in digest messages. The board should only show: task title, project, assignee, and relevant context.
Priority assignment from Slack:
Deduplication: Compare extracted Slack tasks against the Obsidian kanban and Google Drive tasks. Many Slack conversations will reference work already tracked. Only add genuinely new items. If a Slack conversation adds context to an existing task (e.g., a blocking dependency), update the existing task's notes rather than creating a duplicate.
Combine all sources into a single task list. Resolution rules:
Dual-authority completion model: Obsidian AND the Slack Canvas are both authoritative for task completion status. If an item is checked [x] in either Obsidian or the Slack Canvas, it is considered complete. During sync, apply the union of checked states — whichever source has the item marked off wins, and the other source is updated to match. This means team members can check items off on the Canvas and Dorian can check items off in Obsidian, and neither will be overwritten. For all other task metadata (title, tags, column, priority), Obsidian remains the primary source. New tasks found only in the Canvas (added by team via thread replies) are treated as additions.
Google Drive tasks that don't exist in Obsidian get added
Calendar tasks only appear if no existing task covers the same commitment
Gmail tasks only appear if genuinely new action items, not duplicates of tracked work
Slack tasks only appear if they represent commitments/assignments not already tracked in Obsidian or Google Drive. Slack is the richest source of team-distributed action items — many tasks are agreed upon in DMs but never make it to the formal kanban. These are high-value additions.
Enforce column limits: P0 max 3, P1 max 7. If over limit, flag for Dorian's triage
Never display source metadata on the board. Source tracking is internal only — used for deduplication logic. The Canvas and digest messages show only: task title, project (italic), assignee (@-mention), blocking context, and deadlines.
Checked items → In Review (not Done). When a task is found with - [x] (checked) on the Canvas or in the Obsidian kanban (per the dual-authority rule above), do NOT move it directly to Done. Instead, move it to the In Review column. Resolve the reviewer using this priority order:
a) Volunteer override (highest priority): If someone in Slack messages or threads has explicitly volunteered to review a specific task (e.g., "I'll review that", "I can verify"), assign them as the reviewer regardless of the default pairings below.
b) Default review pairings: If no one volunteered, use these standing assignments:
| Assignee (completes the task) | Default Reviewer |
|---|---|
| Dorian | Phil |
| Phil | Dorian |
| Michael | Steven |
| Steven | Michael |
c) Fallback: If the default reviewer is unavailable (e.g., not active on the board, or is the same person who created the task), fall back to Dorian as reviewer.
#review/name tag (e.g., #review/phil, #review/steven)Search the existing Slack Canvas (if one exists) and the #general channel for team-contributed tasks:
slack_search_public with query "Team Kanban" type:canvas in:#generalslack_read_canvas to get its ID and current contentsource: team-input and the contributor's nameFormat the merged task list into Canvas-flavored Markdown. Read references/slack-canvas-format.md for the exact template.
If no Canvas exists yet:
slack_create_canvas titled "Team Kanban — MoxyWolf"If Canvas already exists:
slack_update_canvas using action: replace (full board refresh)Standup sync marker: The Canvas header includes two timestamps:
*Last updated:* — set to the current date/time of this team-kanban sync*Last standup read:* — preserve the existing value from the previous Canvas content. Do NOT overwrite it. This timestamp is written by the morning standup (personal-os plugin) when it reads the Canvas, so the standup can determine which Done/In Review items are new since the last read. If the Canvas is being created for the first time, set this to "never".When the personal-os morning standup reads the Canvas (Step 2 of its flow), it should:
Last standup read timestamp to filter Done items to only those confirmed after that dateLast standup read line on the Canvas to the current timestamp using slack_update_canvas with action: replace on just the header section — or carry the new timestamp forward to the next team-kanban syncAfter updating the Canvas, post a formatted summary message to #general using slack_send_message. Read references/slack-canvas-format.md for the message template.
The digest includes:
This step is mandatory for completion state changes and approval-gated for new tasks.
10a) Completion sync-back (automatic, no approval needed):
If any items were checked on the Slack Canvas but unchecked in Obsidian (detected in Step 6 via the dual-authority rule), update ${VAULT}/Tasks/KANBAN_VIEW.md to match:
- [ ] to - [x] in its current column## 🔍 In Review section with the appropriate #review/name tag10b) New task sync-back (requires Dorian's approval):
If team members added tasks via Slack threads (Step 7), offer to write them back to ${VAULT}/Tasks/KANBAN_VIEW.md:
Triggers: "quick kanban update", "just refresh the board", "push current tasks to Slack"
Skip Steps 4, 5, and 5b (calendar/email/Slack DM scanning). Only read Obsidian + Google Drive, merge, and push to Slack. Faster for mid-day refreshes when the full intelligence scan isn't needed.
Triggers: "set up the team kanban", "create the team board", "initialize the kanban canvas", or the /team-kanban-setup command.
One-time setup flow:
slack_search_channels to find the #general channel and capture its channel IDslack_create_canvas${VAULT}/_Shared Knowledge/Agents and Plugins/team-kanban-config.md with:
Before creating anything new, always check for existing config:
${VAULT}/_Shared Knowledge/Agents and Plugins/team-kanban-config.md if it existsslack_read_canvasIf the config file doesn't exist or the Canvas is gone, fall back to search or prompt for setup.
The Slack digest message should be direct and scannable:
*bold* not **bold**, <url|text> for links)${VAULT}/Tasks/team-kanban-latest.md as a backup.Provides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.
npx claudepluginhub moxywolfllc/moxywolf-plugins --plugin team-kanban