Skip to content

Add Inbox Triage skill - #269

Open
JagmeetChabraMSFT (jchha001) wants to merge 10 commits into
microsoft:mainfrom
jchha001:feat/inbox-triage
Open

Add Inbox Triage skill#269
JagmeetChabraMSFT (jchha001) wants to merge 10 commits into
microsoft:mainfrom
jchha001:feat/inbox-triage

Conversation

@jchha001

Copy link
Copy Markdown
Contributor

Summary

Adds Inbox Triage — a review-first Outlook inbox declutter skill for Scout and Cowork. Sorts inbox mail into five buckets (newsletters, auto-notifications, past-event meeting logistics, resolved threads, redundant duplicates) and moves batches only after per-bucket user approval. Never deletes; only moves to folders under Inbox Triage/ that the user can restore from.

Why this fits the catalog

  • Personal-efficiency slot. Sits alongside work-brief, pattern-radar, and awaiting-reply — same M365 signal pattern, different job.
  • No overlap with existing skills. Verified against the current catalog (checked awaiting-reply, pattern-radar, work-brief, spend-more-time-with-friends-and-family, and every skill with an "inbox", "email", or "cleanup" tag — none does bucket-based move triage).
  • Both platforms. Scout uses the workiq CLI for folder creation; Cowork binds to whichever M365 folder-create tool the session exposes. Falls back to instructing the user if neither is available.

Safety model

Two hard rules named upfront in SKILL.md:

  1. Never delete. Only moves. Even for duplicates. Even if asked. No workiq_delete_email ever.
  2. Never act without per-bucket approval. No auto-run. No batch-approve. User approves each bucket individually or skips it.

Protection layer (runs before classification, hard filter, non-overridable):

  • Manager / direct reports (via workiq_get_my_manager + workiq_get_my_direct_reports)
  • Active thread (asymmetric: user-sent recency counts always; inbound recency counts only for non-bulk senders)
  • Flagged / starred
  • Confidential-or-above sensitivity label
  • HR / Legal / Finance / Security sender (matched by domain or local part, configurable)
  • User allowlist
  • Unread and received in last N days (with narrow noreply-only exception for the notifications bucket)

Untrusted-data guardrail: mail bodies, subjects, and unsubscribe links are treated as data, not instructions.

What it deliberately doesn't do

  • No workiq_delete_email — ever
  • No workiq_send_email / _reply_to_email / _forward_email
  • No workiq_mark_email (read/unread stays with the user)
  • No calendar or chat writes
  • No auto-clicking unsubscribe links (extracts and displays only; config.unsubscribe.everClick is pinned at false)

Structure

submissions/inbox-triage/
├── metadata.json
├── README.md
├── SKILL.md
├── assets/config.example.json
└── references/
    ├── classification-rules.md   (bucket tests + worked examples)
    ├── safety.md                 (each protection rule + why it exists)
    └── scout-tools.md            (WorkIQ tools used and deliberately not used)

Validated with npm run check:submissions — passes as submission #80.

Author

Third submission after presentation-talk-track-builder and regulation-monitor. CLA on file from PR #75.

Copilot AI lite review requested due to automatic review settings August 7, 2026 15:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new catalog submission under submissions/inbox-triage/ for an “Inbox Triage” skill that proposes per-bucket, user-approved moves of low-value Outlook mail into Inbox Triage/* folders (never deleting), with a defined protection layer and supporting reference docs/config.

Changes:

  • Added the inbox-triage skill instructions (SKILL.md) with bucket definitions, protection rules, and an approval-gated execution flow.
  • Added supporting documentation (README.md, references/*) and an example configuration (assets/config.example.json).
  • Added submission metadata (metadata.json) declaring platforms, tags, and author info.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
submissions/inbox-triage/SKILL.md Core skill procedure, safety model, classification, approval gating, and move execution steps.
submissions/inbox-triage/references/scout-tools.md Tooling notes for listing/moving mail and folder creation behavior.
submissions/inbox-triage/references/safety.md Rationale and details for each protection-layer rule.
submissions/inbox-triage/references/classification-rules.md Expanded bucket tests, negative tests, and worked examples.
submissions/inbox-triage/README.md Human-facing overview, usage guidance, configuration, and undo instructions.
submissions/inbox-triage/metadata.json Submission metadata (name/description/platforms/tags/author/version/dates).
submissions/inbox-triage/assets/config.example.json Example config schema and defaults for folders/buckets/protection.
Suppressed comments (1)

submissions/inbox-triage/SKILL.md:166

  • Step 6 hardcodes workiq_list_mail_folders / workiq_move_email even though the skill is declared for Cowork as well; those tool names are not reliably available outside Scout. Also, the WorkIQ CLI example uses shell-dependent quoting for the JSON payload; on Windows workiq.cmd under cmd.exe the single-quote form will not work. Update Step 6 to use the bound mail-folder/move capabilities per platform and to invoke the CLI without relying on shell quoting.
1. **Resolve the destination folder ID, creating parent and child as needed.** Values under `config.folders.*` are folder path/name strings (never raw IDs). For each bucket:
   - List Inbox child folders with `workiq_list_mail_folders` (`folder: "Inbox"`, `recursive: false`) and look for the parent named by the leading segment of the configured path (default `Inbox Triage`). If missing, create it as a child of Inbox (Step 6.2).
   - List that parent's child folders and look for the bucket name (default `Newsletters`, `Notifications`, `Past events`, `Resolved`, `Duplicates`). If missing, create it as a child of the parent (Step 6.2).
   - Use the resulting bucket folder ID as `destination` for the moves.
2. **Create a folder when it does not exist.** Bind to whichever mail-folder create capability the running session exposes:
   - On **Scout**, shell out to the WorkIQ CLI: `workiq create --path "/me/mailFolders/{parent-id}/childFolders" --json '{"displayName": "<Folder Name>"}'`. Discover `{parent-id}` from the listing in Step 6.1 (for the parent, use Inbox's ID from the folders list). The `workiq` CLI is at `~/.scout/bin/workiq.cmd` on Windows and `~/.scout/bin/workiq` on macOS/Linux; do not assume a global PATH entry. Treat a Graph "folder already exists" or "conflict" response as success and re-resolve the folder ID from a fresh listing. On any other failure, fall through to the user-instruction path below.
   - On **Cowork**, bind to the M365 mail-folder create tool exposed in the session. Names vary by build - inspect the tool list and use whichever matches "create mail folder". Same "already exists" and "on other failure" handling.
3. **If folder creation is not possible in the session** (no CLI, no matching MCP tool, or the create call failed for a reason other than already-exists), stop the affected bucket and tell the user to create the folder manually in Outlook, giving them the exact folder name. Never fall back to a different destination folder, and never guess at a create-tool name that is not confirmed available in the running session.
4. **Handle already-moved messages gracefully.** A retried run may find that some approved message IDs are no longer in Inbox (a prior run moved them, or the user moved them manually). Attempt the move; if `workiq_move_email` reports the message is not found in Inbox, count it as already-moved and continue. Do not re-list the Inbox and do not rebuild the plan.
5. **Move via `workiq_move_email`** using the resolved folder ID as `destination`. Execute one bucket to completion before starting the next; do not parallelise moves across buckets. If the tool supports only one message per call in the current build, move serially and report progress ("moved 50 of 312").
6. **On any move failure other than not-found, stop the bucket, keep what already moved, and report** the failure with the specific message and error. Do not retry silently.

Comment on lines +20 to +21
- On **Scout**, shell out to the WorkIQ CLI (`~/.scout/bin/workiq.cmd` on Windows, `~/.scout/bin/workiq` on macOS/Linux). Use `workiq create --path "/me/mailFolders/{parent-id}/childFolders" --json '{"displayName": "<Folder>"}'`. Discover the Inbox ID from `workiq_list_mail_folders` at run time. A "folder already exists" response is treated as success.
- On **Cowork**, bind to whichever M365 mail-folder create tool the session exposes. Names vary by build; inspect the tool list.
Comment on lines +46 to +65
## Step 1 - Collect

Tool names and calling patterns are in `references/scout-tools.md`. Read it before the first call. If an expected tool is unavailable, do not silently continue - report it and stop; a partial triage that skips protection lookups is worse than none.

**Mail.** `workiq_list_emails` on the inbox over the lookback window. For every message pull: `id`, `conversationId`, subject, sender address, sender display name, received time, `isRead`, `flag.flagStatus`, folder ID, sensitivity label, `hasAttachments`, and the header material needed to detect `List-Unsubscribe` (`internetMessageHeaders`). **Do not open message bodies** unless a message survives all buckets and needs disambiguation - bodies are expensive and unnecessary for classification.

Paginate as required by the tool. If the tool returns a truncation marker or hits a hard cap, do not proceed as though the inbox is fully covered - stop and tell the user the size and ask whether to run over a narrower window instead. Silent truncation would leave protected mail unaccounted for.

**Sent, for the active-thread test.** One `workiq_list_emails` call on the Sent folder over the active-thread window (default 14 days). Pull `id`, `conversationId`, To/Cc recipient addresses, and sent time. Do not pull bodies. You use this to answer: "has the user emailed anyone at this address recently?"

**Sent, for the `resolved` bucket.** A second `workiq_list_emails` call on the Sent folder over the full lookback window. Pull `id`, `conversationId`, and sent time only. You need this to determine whether the newest message in a thread (across Inbox and Sent) is from the user; the Inbox listing alone cannot answer that.

**Org context, for the protection layer.**

- `workiq_get_my_manager` - once.
- `workiq_get_my_direct_reports` - once.

Cache both for the run. Never call again per-message. Distinguish an empty *successful* result from a *failed* call: an empty result (a user without a manager, or a user with no direct reports) is a normal response - proceed with the other protection rules and note in the plan which parts of the org-chart rule contributed. A failed call, timeout, or unavailable tool aborts the run - see `references/scout-tools.md`.

**Calendar.** Not called. Past-event meeting logistics are detected from the mail subject line and received date; calendar access adds cost without adding accuracy.
Copilot AI review requested due to automatic review settings August 7, 2026 15:59
@jchha001

Copy link
Copy Markdown
Contributor Author

Addressed both bot review comments in ea86b8d:

  1. Windows shell quoting on WorkIQ CLI (scout-tools.md:21) — Step 6.2 now describes invoking workiq directly as an executable with each argument as a separate argv entry, including the JSON body. No shell quoting needed; works the same under cmd.exe, PowerShell, bash, and zsh.

  2. Hardcoded Scout tool names in a Cowork-declared skill (SKILL.md:65, 156) — Refactored to describe capabilities (list mail, get profile, move mail, create folder, etc.) with per-platform tool-name guidance (typical workiq_* on Scout, m365_* on Cowork). Renamed references/scout-tools.mdreferences/tools.md and rebuilt it around a capabilities table. Step 0 now instructs the agent to inspect the running session's tools and bind capabilities before Step 1.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (5)

submissions/inbox-triage/SKILL.md:25

  • This step says to bind each capability in references/tools.md and stop if any is missing. That list includes execution-only capabilities (not needed to build the plan), and the skill also documents a manual fallback if folder creation isn't available. Consider only requiring the collection + protection capabilities before Step 1, and deferring execution capability validation until Step 6.

(Ref: submissions/README.md:36-40 emphasizes keeping SKILL.md focused on agent/runtime instructions.)

The skill runs on both Cowork and Scout. Tool names differ by platform - Scout typically exposes them under `workiq_*`, Cowork typically under `m365_*`. **Do not hardcode a specific tool name**; before Step 1, inspect the tools available in the session and bind each capability listed in `references/tools.md`. If any required capability has no binding, report which one is missing and stop.

submissions/inbox-triage/SKILL.md:30

  • SKILL.md is agent-facing at runtime; setup/how-to-adopt guidance is expected to live in the submission README.md instead (submissions/README.md:36-40). The sentence instructing the reader to copy assets/config.example.json into ~/.copilot/... is human-facing setup and can be moved/handled via the README, while keeping the runtime rule here as “read config if present; otherwise use defaults / ask user”.
2. **The config file** at `~/.copilot/inbox-triage/config.json`, if present. `assets/config.example.json` is a complete example config - copy it to that path and edit it. If the file exists but is unreadable or fails to parse as JSON, stop and report - do not fall back to defaults silently, since silent fallback is the exact failure mode that would move mail with settings the user never approved.

submissions/inbox-triage/references/tools.md:9

  • This paragraph treats every capability in the table as a required upfront binding and says to stop if any is missing, but the table itself includes execution-only items (e.g., folder creation) and the document later describes a manual fallback when folder creation isn't available. To avoid contradictory run behavior, tighten the “stop if missing” rule to only the collection + protection capabilities, and treat execution-only capabilities as validated later with fallback handling.
At the start of every run, inspect the tools available in the session and bind these capabilities. If a required capability has no available tool binding, do not silently continue - report which capability is missing and stop. A triage skill that skips org-chart protection because a lookup tool was missing is much worse than one that says "profile lookup unavailable, aborting". The whole safety promise of the skill is the protection layer; a triage run without it is a foot-gun.

submissions/inbox-triage/references/tools.md:29

  • This section states the WorkIQ CLI lives at ~/.scout/bin/workiq(.cmd), but then says the command is just workiq. Unless the CLI is guaranteed to be on PATH, this is inconsistent and can cause the folder-create step to fail. Align the command with the documented platform-specific path.
  - Command: `workiq`

submissions/inbox-triage/SKILL.md:92

  • The bucket-signal patterns in this table include literal \| (e.g., newsletter\|digest...). That reads as a backslash + pipe, which can lead to implementing the classifier with the wrong regex/string patterns. In GitHub-flavored Markdown tables, | inside inline code spans is safe, so these backslashes can be removed.
| `newsletters` | Presence of `List-Unsubscribe` header, or sender domain in a known bulk-mail list (substack, mailchimp, marketo, sendgrid, mailerlite, convertkit, hubspot marketing, ...), or sender local part matches `newsletter\|digest\|weekly\|updates\|marketing\|hello\|news`. | `folders.newsletters` (default `Inbox Triage/Newsletters`) |
| `notifications` | Sender address starts with `noreply\|no-reply\|notifications\|alerts\|donotreply\|automated\|system\|robot\|bot`. Or sender is a known automation platform (Jira, Azure DevOps, GitHub, GitLab, ServiceNow, PagerDuty, Datadog, Snyk, Dependabot, ...). | `folders.notifications` (default `Inbox Triage/Notifications`) |

Copilot AI review requested due to automatic review settings August 7, 2026 16:11

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

submissions/inbox-triage/SKILL.md:175

  • The Scout Windows folder-creation instructions assume ~/.scout/bin/workiq.cmd can be invoked “directly as an executable” with argv semantics, but .cmd is a batch wrapper and requires a shell (cmd.exe /c) which will re-parse/escape the JSON argument. As written, this step is likely to fail on Windows and undermines the cross-OS claim. Please update the guidance to require a real executable on Windows (e.g., workiq.exe if present) or treat auto-create as unavailable and use the manual-folder fallback. Mirror the same correction in references/tools.md.
   - On **Scout**, invoke the WorkIQ CLI directly as an executable (not through a shell interpreter that would try to parse quotes). Use the absolute path since the CLI is not guaranteed to be on `PATH`:
     - Windows: `~/.scout/bin/workiq.cmd`
     - macOS/Linux: `~/.scout/bin/workiq`
     
     Resolve `~` via the runtime. Pass these arguments, each as a separate argv entry:

submissions/inbox-triage/references/tools.md:41

  • This section makes the same Windows assumption as SKILL.md: workiq.cmd cannot be invoked “directly as an executable” with argv semantics. On Windows it must run under cmd.exe, which changes argument parsing/escaping (notably for the JSON body), so the current “works the same under cmd.exe/PowerShell/bash/zsh” statement is not accurate. Please adjust to require a real executable on Windows (if available) or fall back to manual folder creation instructions.
- On **Scout**, no MCP-level create tool is currently exposed, but the platform ships a CLI that can call any Microsoft Graph endpoint. Invoke it directly as an executable (not through a shell interpreter that would try to parse quotes):
  - Command (absolute path, since the CLI is not guaranteed to be on `PATH`):
    - Windows: `~/.scout/bin/workiq.cmd` (resolve `~` via the runtime)
    - macOS/Linux: `~/.scout/bin/workiq` (resolve `~` via the runtime)
  - Arguments (each as a separate argv entry, no shell quoting):

Copilot AI review requested due to automatic review settings August 7, 2026 16:35
@jchha001

Copy link
Copy Markdown
Contributor Author

Addressed both bot comments in 4bae19e after live testing on Windows:

  1. Windows .cmd argv/JSON issue is real. Tested the WorkIQ CLI on Windows with several quoting strategies (PowerShell native argv, cmd /c with escaped quotes, backtick-escaped double quotes). cmd.exe strips or mangles double quotes in every case, and workiq create does not currently accept --body via a file or stdin — only inline. Rather than paper over the flaw:

    • Scout macOS/Linux: use the CLI (POSIX shells preserve argv cleanly)
    • Scout Windows: skip auto-create, use the manual-folder fallback
    • Cowork: use the M365 folder-create tool
  2. CLI flag names were wrong. My original text used --path / --json (which I hallucinated); workiq create --help shows the real flags are -u / --url and -b / --body. Corrected in SKILL.md and references/tools.md.

README setup section now reflects: zero setup on Cowork and macOS/Linux Scout, one-time folder creation on Windows Scout.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

submissions/inbox-triage/SKILL.md:202

  • SKILL.md should stay agent-facing; setup/tips for humans (like copying the example config to a local path) should live in README.md instead (see submissions/README.md:74-82). This bullet reads like human setup guidance and can be removed without affecting runtime behavior.
- `references/tools.md` - capabilities the skill binds to per-platform tools, calling patterns, and what to do when a capability is missing.
- `references/classification-rules.md` - bucket tests, sender-domain lists, unsubscribe detection, and worked examples.
- `references/safety.md` - the protection layer in detail, why each rule exists, and how to extend it in config.
- `assets/config.example.json` - annotated example config; copy to `~/.copilot/inbox-triage/config.json` and edit.

Copilot AI review requested due to automatic review settings August 7, 2026 16:50

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

submissions/inbox-triage/SKILL.md:163

  • Step 6.2 says to use a folder-create tool “bound in Step 0”, but Step 0 explicitly says create-folder is execution-only and should be checked at Step 6. This contradiction makes the runbook ambiguous and can lead to the agent trying to use an unbound/guessed tool name at execution time.
   - On **Cowork**, use the M365 folder-create tool bound in Step 0. Names vary by build - inspect the tool list. Treat a "folder already exists" or HTTP 409 response as success and re-resolve the folder ID from a fresh listing.

submissions/inbox-triage/SKILL.md:175

  • Step 6 references a “bound” move-email capability, but never states where/how to bind it or what to do if no move capability exists in the session. Without this, the agent may guess a tool name or attempt moves that cannot succeed.
5. **Move via the bound "move email" capability** using the resolved folder ID as `destination`. Execute one bucket to completion before starting the next; do not parallelise moves across buckets. If the tool supports only one message per call in the current build, move serially and report progress ("moved 50 of 312").

Copilot AI review requested due to automatic review settings August 7, 2026 18:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

submissions/inbox-triage/SKILL.md:87

  • Step 3 is currently written as if the table’s “positive signals” are the full classification spec, but several critical blocking rules live only in references/classification-rules.md (e.g., routing notifications@github.com security advisories to Inbox, and avoiding internal-domain automation/newsletters). Without explicitly requiring the negative tests, an implementation could follow this section and still move mail that the references say must stay in Inbox.
Assign each surviving candidate to exactly one bucket. **Skip any bucket whose `config.buckets.<bucket>.enabled` is `false`** - a disabled bucket is never proposed and never executed, even if candidates match its signals. A message is only in a bucket if the bucket's positive signal is strong; when in doubt, leave it in the inbox.

submissions/inbox-triage/SKILL.md:93

  • The past-events bucket summary omits key parts of the bucket’s own definition in references/classification-rules.md: it should require a calendar-system/calendar-response sender signal, and it must not propose moving responses for meetings that are still in the future or part of an ongoing recurring series. As written, any message with an Accepted:-style subject older than 7 days could be swept in.
| `past-events` | Subject starts with `Accepted:`, `Declined:`, `Tentative:`, `Canceled:`, `Updated invitation:` - or a localised prefix listed in `config.meetingResponsePrefixes` - AND the message is older than `pastEventMinAgeDays` (default 7 days). | `folders.pastEvents` (default `Inbox Triage/Past events`) |

Copilot AI review requested due to automatic review settings August 7, 2026 19:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

A review-first Outlook inbox declutter tool that sorts mail into five
buckets (newsletters, notifications, past-event logistics, resolved
threads, duplicates) and moves batches only after per-bucket user
approval. Never deletes. Broad protection layer keeps manager, direct
reports, active threads, flagged mail, HR/Legal/Finance/Security
senders, sensitivity-labelled mail, and allowlisted senders untouched.

Runs on Scout (via workiq CLI for folder creation) and Cowork (via
M365 folder-create tool). Falls back to instructing the user manually
if neither is available.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…cation

Two bot review comments addressed:

1. Windows shell quoting on workiq CLI: rewrote Step 6.2 to invoke
   workiq as an executable with argv entries (not shell-quoted JSON),
   so folder creation works the same under cmd.exe, PowerShell, bash,
   and zsh.

2. Cowork tool naming: replaced hardcoded workiq_* names throughout
   Step 0/1/6 with capability descriptions bound at runtime to either
   workiq_* on Scout or m365_* on Cowork. Renamed references/scout-tools.md
   to references/tools.md and rebuilt it around a capabilities table.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…escape pipes

Five suppressed bot comments addressed:

1. Upfront capability check too broad. Step 0 and tools.md now require
   only collection + protection capabilities upfront; execution-only
   capabilities (move, create) are validated at Step 6 with a fallback.

2. Setup guidance in SKILL.md is human-facing. Removed the 'copy
   assets/config.example.json to ~/.copilot/...' instruction from SKILL.md
   (which is agent-facing); it already lives in README.md.

3. Same as microsoft#1 in references/tools.md.

4. WorkIQ CLI command path inconsistency. Step 6.2 and tools.md now
   spell out the absolute path per platform since the CLI is not
   guaranteed to be on PATH.

5. Unnecessary backslash escaping of pipes in markdown table code
   spans. Removed '\|' -> '|' in bucket-signal patterns so the classifier
   is not implemented with literal backslash-pipe.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lags

Two suppressed bot comments addressed after live testing on Windows:

1. Windows .cmd argv/JSON issue is real (bot was correct). Tested the
   WorkIQ CLI on Windows with several quoting strategies; cmd.exe strips
   or mangles double quotes in every case, and the CLI has no --body-file
   or stdin option. Split the guidance:

   - Scout macOS/Linux: use CLI, POSIX argv is clean.
   - Scout Windows: skip auto-create entirely, use manual-folder fallback.

2. CLI flag names were wrong (--path/--json were invented; the real
   flags are -u/--url and -b/--body). Corrected in SKILL.md and tools.md.

Also updated README setup section to reflect: zero setup on
Cowork/macOS/Linux Scout, one-time folder creation on Windows Scout.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bot suppressed comment: the last bullet in the References list read
like human setup guidance (copy config.example.json to ~/.copilot/...).
Reworded to be a runtime-facing description of the config schema.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two bot suppressed comments addressed:

1. Step 6.2 referenced 'M365 folder-create tool bound in Step 0' but
   Step 0 explicitly defers execution capabilities. Fixed: Step 6.2 now
   binds create-mail-folder at execution time with the typical
   tool-name guidance inline.

2. Step 6.5 referenced 'the bound move email capability' without
   saying where it was bound. Fixed: Step 6.5 now binds move-email
   at execution time with typical Scout/Cowork tool names and a
   stop-on-missing rule.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Two bot suppressed comments addressed:

1. Step 3 preamble now explicitly states the table lists positive
   signals only and that negative tests in classification-rules.md
   are required. Warns that skipping them moves mail the skill's own
   rules say must stay in inbox.

2. past-events row now includes the calendar-system sender requirement
   and calls out the future-meeting and ongoing-recurring-series
   negative tests inline so they cannot be missed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (1)

submissions/inbox-triage/SKILL.md:99

  • past-events is used as the bucket identifier here, but the config schema uses camelCase (buckets.pastEvents and folders.pastEvents in assets/config.example.json). This mismatch can cause user config (e.g., disabling the past-events bucket) to be ignored or applied incorrectly. Please standardize the bucket key across SKILL.md, references/classification-rules.md, and assets/config.example.json (for example: use pastEvents as the config/bucket key everywhere, while keeping the user-facing label "Past events").
| `past-events` | Subject starts with `Accepted:`, `Declined:`, `Tentative:`, `Canceled:`, `Updated invitation:` - or a localised prefix listed in `config.meetingResponsePrefixes` - AND the message is older than `pastEventMinAgeDays` (default 7 days) AND sender is a calendar system (Outlook / Exchange / Teams). Negative tests (see references): the referenced meeting must not be in the future, and must not be part of an ongoing recurring series. | `folders.pastEvents` (default `Inbox Triage/Past events`) |
| `resolved` | Across the Inbox and Sent listings from Step 1, the newest message for this `conversationId` is FROM the user, the newest message is older than `resolvedThreadMinAgeDays` (default 60 days), and no newer inbound reply exists. If thread state cannot be verified from the collected listings, leave in inbox. | `folders.resolved` (default `Inbox Triage/Resolved`) |
| `duplicates` | Older message in a thread where a newer message on the same `conversationId` is present in the inbox. The older ones are the duplicates; the newest stays. | `folders.duplicates` (default `Inbox Triage/Duplicates`) |

If a message matches signals for two buckets, prefer `notifications` over `newsletters` over `past-events` over `duplicates` over `resolved`, in that order.

Bot review 8 flagged: SKILL.md and references/classification-rules.md
used 'past-events' (kebab-case) as the bucket identifier while
assets/config.example.json uses 'pastEvents' (camelCase) under
buckets.* and folders.*. A user disabling buckets.pastEvents in
config would not match the past-events bucket key at runtime.

Standardized on 'pastEvents' across SKILL.md and
references/classification-rules.md; user-facing folder label stays
'Past events' (with a space) which is fine because it's a display
string, not a lookup key.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 11, 2026 14:29

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Suppressed comments (4)

submissions/inbox-triage/README.md:50

  • This protection-layer note says manager/direct-report lookups are resolved via WorkIQ, but Cowork runs via M365 tools rather than WorkIQ. Consider making this bullet platform-neutral to avoid implying WorkIQ is required on Cowork.
- **From your manager or a direct report.** Resolved once per run via WorkIQ.

submissions/inbox-triage/README.md:66

  • This says “Zero setup on Cowork… the skill creates the destination folders”, but SKILL.md explicitly allows for sessions where no folder-create capability is available and falls back to manual folder creation. The README should reflect that possibility to avoid overpromising.
Zero setup on Cowork and on macOS/Linux Scout - the skill creates the destination folders under `Inbox Triage/` automatically on first run.

submissions/inbox-triage/SKILL.md:30

  • This line says the config setup guidance lives in the submission README, but README.md is not bundled / seen by the agent at runtime (see CONTRIBUTING.md:24 and submissions/README.md:16-18). The skill should not depend on the agent being able to consult the README; point to the bundled example config instead (or omit the aside).
2. **The config file** at `~/.copilot/inbox-triage/config.json`, if present. If the file exists but is unreadable or fails to parse as JSON, stop and report - do not fall back to defaults silently, since silent fallback is the exact failure mode that would move mail with settings the user never approved. (Setup guidance for creating this file lives in the submission README, not here.)

submissions/inbox-triage/README.md:9

  • The README currently frames usage as Scout-only, but the submission targets both Cowork and Scout. This can confuse Cowork users; update the wording to be platform-neutral.

This issue also appears in the following locations of the same file:

  • line 50
  • line 66
Once the skill is imported into Scout, ask for it in plain language:


- **Manager lookup returns no result** for a user without one (contractors, C-suite, sole proprietors). This is a normal response, not a failure. Treat as "no protection from this rule for a manager" and proceed. Report in the plan: "Manager: none returned - org-chart protection applied for direct reports only."
- **Direct reports lookup returns empty**. Same handling.
- **Sensitivity label field missing** on some messages. Treat as unlabelled and rely on other protection rules. Do not fabricate a label.
…utral

Bot review 9: one blocking + four suppressed comments, all valid.

Blocking:
- Missing sensitivity-label field was previously treated as 'unlabelled
  and rely on other rules'. That's unsafe: label unknown is not label
  absent, and the whole point of the rule is to never touch anything
  that might be Confidential. Now treated as protected under a
  'label unknown' reason.

Suppressed:
- README 'via WorkIQ' implied WorkIQ required on Cowork. Reworded to
  'the platform's M365 lookup (WorkIQ on Scout, equivalent M365 tool
  on Cowork)'.
- README 'Zero setup on Cowork and macOS/Linux Scout' overpromised
  since SKILL falls back to manual folder creation when the
  create capability isn't exposed. Reworded to 'In most sessions...'
  with the two exception cases spelled out.
- SKILL.md Step 0 pointed to README for config setup guidance, but
  README isn't bundled to the agent at runtime. Removed the aside;
  pointed to assets/config.example.json (which is bundled).
- README basic usage said 'Once the skill is imported into Scout'
  which was Scout-only framing for a Scout+Cowork skill. Reworded
  to 'imported into Scout or Cowork'.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 11, 2026 14:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Set author to 'Jagmeet Chabra (Microsoft)' and add explicit
authorGithub 'jchha001' so the skillbot @-mention still resolves now
that the author string is no longer a bare GitHub handle. authorUrl
still points to the GitHub profile.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings August 11, 2026 18:42

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants