archived/skills/email-triage/SKILL.md
Email triage workflow with mandatory archive receipt logging to task body
npx skillsauth add nicsuzor/academicops email-triageInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Taxonomy note: This skill provides domain expertise (HOW) for email triage and task capture. See [[TAXONOMY.md]] for the skill/workflow distinction.
Triage inbox emails with MANDATORY archive receipt logging. Receipts are written to task body concurrently during execution, not after.
Every archive operation MUST produce a receipt log in the task body.
This is non-negotiable. The user cannot audit or revert archive operations without receipts. Writing receipts to scratchpad is UNACCEPTABLE - scratchpad is ephemeral, task body is persistent.
## Archive Receipt Log (N emails)
| # | Date | From | Subject |
| --- | ---------- | ---------------- | ----------------------------------- |
| 1 | 2025-11-19 | Email Quarantine | End User Digest: 7 New Messages |
| 2 | 2025-11-19 | QUT Travel | Your Travel (#893940) has concluded |
| ... | | | |
All N emails moved to [Archive Folder] folder.
WRONG (batch at end - data loss risk):
1. Archive email 1
2. Archive email 2
...
N. Archive email N
N+1. Write all receipts to task body # If this fails, ALL receipts lost
RIGHT (concurrent - partial receipt on failure):
1. Archive email 1 → immediately append receipt to task body
2. Archive email 2 → immediately append receipt to task body
...
N. Archive email N → immediately append receipt to task body
MANDATORY: This skill requires a task to write receipts to.
# Option A: Use existing task
task_id = "<provided-task-id>"
# Option B: Create new task — resolve parent per [[references/hierarchy-quality-rules]] first
result = mcp__pkb__create_task(
task_title="Email triage: [date range/criteria]",
type="task",
project="<project>",
parent="<resolved-parent-id>",
tags=["email", "triage"]
)
task_id = result["task"]["id"]
If no task is bound, HALT. Do not proceed without a task ID for receipt logging.
Before archiving ANY emails, initialize the receipt table header in the task body:
mcp__pkb__update_task(
id=task_id,
body="""## Archive Receipt Log
| # | Date | From | Subject |
|---|------|------|---------|"""
)
Fetch emails based on criteria:
# Recent emails (using ~~email connector)
emails = ~~email.messages_list_recent(limit=50, folder="inbox")
# Or search by criteria
emails = ~~email.messages_search(
subject="keyword",
person="[email protected]",
is_unread=True
)
Classification categories (semantic, not keyword-based):
| Category | Description | Action | | -------- | -------------------------------------- | ------------------- | | Task | Requires action, response, or decision | Create task | | FYI | Useful information, no action needed | Read and archive | | Skip | Spam, irrelevant, auto-generated noise | Archive immediately |
Classification guardrails:
Reply-waiting signals (ALWAYS Task, never FYI):
MANDATORY: Get user approval before archiving.
Use AskUserQuestion to present:
AskUserQuestion(
questions=[{
"question": "Ready to archive N emails (X Skip, Y FYI)?",
"header": "Archive",
"options": [
{"label": "Archive all", "description": "Proceed with archiving classified emails"},
{"label": "Review first", "description": "Show me the full list before archiving"},
{"label": "Cancel", "description": "Do not archive anything"}
],
"multiSelect": False
}]
)
For each email to archive:
~~email.messages_move(
entry_id=email["entry_id"],
folder_path="Archive" # Or user-specified folder
)
mcp__pkb__update_task(
id=task_id,
body=f"| {count} | {email['date']} | {email['from']} | {email['subject']} |"
)
Do NOT batch receipt writes. Each archive operation = immediate receipt append.
After all emails archived, append summary:
mcp__pkb__update_task(
id=task_id,
body=f"\nAll {total_count} emails moved to {folder_name} folder."
)
Interactive Supervised Mode is an extension of the standard 6-step workflow for runs where a human is actively supervising (human-in-the-loop). All of Steps 1–6 still apply, including the mandatory user checkpoint in Step 4; the rules below are additional guardrails that change how you execute those steps when the user is available for real-time review.
AskUserQuestion to present options — never assume dates or availabilityWhen drafting responses, follow these requirements:
Before drafting ANY response, load the user's email style guide from memory:
mcp__pkb__search(query="email style guide")
If no style guide is found, use these defaults:
For 100+ emails, use chunking per [[workflows/batch-processing]]:
Spawn parallel workers, each with the task ID for receipt logging:
Task(
subagent_type="general-purpose",
prompt=f"""Process Nov 2025 emails for triage.
Task ID for receipts: {task_id}
For EACH email archived, IMMEDIATELY append receipt:
mcp__pkb__update_task(
id='{task_id}',
body='| N | DATE | FROM | SUBJECT |'
)
Classification criteria: [criteria]
Archive folder: Archive
""",
run_in_background=True
)
Each worker is responsible for its own receipts. The supervisor does NOT aggregate receipts after the fact - they are written during execution by each worker.
| Error | Response | | ----------------------- | ---------------------------------------------------------------------------------- | | Archive fails mid-batch | Task body contains partial receipt up to failure point - audit trail preserved | | Task update fails | HALT immediately. Log error. Do NOT continue archiving without receipt persistence | | ~~email unavailable | HALT. Do not proceed without email access | | No task bound | HALT. Create or specify task before any archive operations |
Before marking triage complete:
Task body after successful triage:
# Email triage: QUT inbox (Nov 2025 - Feb 2026)
## Archive Receipt Log (188 emails)
| # | Date | From | Subject |
| --- | ---------- | ---------------------------- | ----------------------------------- |
| 1 | 2025-11-19 | Email Quarantine | End User Digest: 7 New Messages |
| 2 | 2025-11-19 | QUT Travel | Your Travel (#893940) has concluded |
| 3 | 2025-11-18 | QUT DVC Research | Read and Publish Agreement Update |
| ... | | | |
| 188 | 2026-02-01 | [email protected] | Web of Science Alert |
All 188 emails moved to QUT Archive folder.
tools
Streamlit implementation of the analyst presentation layer. Use when building or updating a Streamlit dashboard that displays pre-computed research data. This is the Streamlit-specific HOW for the tech-agnostic principles in the aops-tools analyst skill — display only, never transform.
tools
Python plotting and statistical-modelling libraries (matplotlib, seaborn, statsmodels) for the analyst presentation and statistical-methodology layers. Use when producing publication-quality figures or fitting statistical models in Python. Library-specific HOW for the tech-agnostic principles in the aops-tools analyst skill.
tools
dbt (data build tool) implementation of the analyst transformation layer. Use when a project has a dbt/ directory or you need to build, test, or document SQL transformations as version-controlled, reproducible dbt models. This is the dbt-specific HOW for the tech-agnostic principles in the aops-tools analyst skill.
development
Core academicOps skill — institutional memory, strategic coordination, workflow routing, and framework governance. Merges butler (chief-of-staff) with framework development conventions.