feat(triage): classify important emails into Stanier action categories on Asana - #7
Merged
Merged
Conversation
…s on Asana Add an email -> Asana management-action triage capability integrated into the `process` pipeline. Important emails (scored by sender tier + customer/escalation boosts) are classified by an LLM into one of four Stanier management-action categories (Information Gathering, Nudging, Being the Example, Taking Decision), each mapped to a dedicated Asana project. An idempotent rich task is created with a target date extracted from the email's deadline, category standard text, and a definition-of-done. - triage.py: deterministic sender-tier scoring (name+address match), customer (external-domain) + escalation/asked-of-me boosts, recall-biased body fetch, one mocked LLM boundary for category + deadline, idempotent task assembly - asana_client.py: module-level httpx, validate-only (never auto-creates), paginated dedup search by kontor-id:<message-id|uid> marker, create_task - himalaya.py: read-only body (--no-headers --preview) + Message-ID header read; Email gains from_name from the envelope - pipeline.py: triage fires on content after classification, before/independent of the move; LOUD up-front project validation; per-email errors skip+log with triage_tasks_created/skipped_dedup/skipped_error counters in the summary - cli.py: preview-only `kontor-cli triage --dry-run` - config: optional asana + triage sections, conditional fail-fast validation - .agents/skills/email-to-asana/SKILL.md: rubric, 4 category templates, runbook TDD throughout: 236 tests pass, coverage 93% (>=90 gate), ruff + mypy strict clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds an email → Asana management-action triage capability, integrated into
kontor-cli process. Important emails are scored for importance (sender tiers + customer/escalation boosts), classified by an LLM into one of four Stanier management-action categories — Information Gathering, Nudging, Being the Example, Taking Decision (from Becoming an Effective Software Engineering Manager) — and each becomes an idempotent Asana task in that category's dedicated project, with a target date extracted from the email's deadline, category standard text, and a definition-of-done.Built via deep-interview → ralplan consensus (Architect + Critic APPROVE) → team execution → code-review loop. Plan:
.omc/plans/email-to-asana-triage.md.What's included
triage.py— deterministic sender-tier scoring (matches by name + address), customer (external-domain) boost, escalation/asked-of-me boost for internal colleagues, recall-biased body fetch, one LLM boundary for category + deadline, idempotent task assembly. 4 category templates encoded verbatim (standard text + done-when).asana_client.py— module-levelhttpx, validate-only (never auto-creates projects/fields), paginated dedup search bykontor-id:<message-id|uid>marker,create_task.himalaya.py— read-only body (--no-headers --preview, no seen flag) + Message-ID header read;Emailgainsfrom_namefrom the envelope.pipeline.py— triage fires on content after classification, independent of the move outcome; LOUD up-front project validation; per-email errors skip+log withtriage_tasks_created/triage_skipped_dedup/triage_skipped_errorscounters in the run summary.cli.py— preview-onlykontor-cli triage --dry-run.asana+triagesections with conditional fail-fast validation (_validate_required);config.example.yamlseeded with sender tiers..agents/skills/email-to-asana/SKILL.md— rubric, the 4 category templates, config + dry-run-first runbook, failure boundary.Safety / invariants
triageis preview-only; writes happen only viaprocess.config.yaml; example uses a placeholder.Tests
TDD throughout — 236 tests pass, coverage 93% (≥90 gate),
ruff check+ruff format --check+mypy --strictall clean.🤖 Generated with Claude Code