diff options
| -rw-r--r-- | .ai/workflows/triage-intake.personal-gmail.org | 15 | ||||
| -rw-r--r-- | claude-templates/.ai/workflows/triage-intake.personal-gmail.org | 15 |
2 files changed, 30 insertions, 0 deletions
diff --git a/.ai/workflows/triage-intake.personal-gmail.org b/.ai/workflows/triage-intake.personal-gmail.org index a7af333..7d1ab4d 100644 --- a/.ai/workflows/triage-intake.personal-gmail.org +++ b/.ai/workflows/triage-intake.personal-gmail.org @@ -25,6 +25,21 @@ mcp__google-docs-personal__listMessages q="is:unread in:inbox after:<anchor-epo ⚠ *Do NOT add =-category:promotions -category:social=.* That filter masked 67 promo+social messages across two runs (2026-05-04, 2026-05-06), both needing a follow-up sweep. Pull the full unfiltered set; the trash-leaning bias in Classify handles promotions and social directly. +⚠ *The MCP caps at =maxResults=100= and exposes NO =pageToken= parameter.* The response carries a =nextPageToken=, but the tool can't consume it, so a pile over 100 is silently truncated — the tail below the cap never gets classified, and every later anchored sweep skips it (it predates the new anchor). This is exactly how a 300+ backlog accumulated invisibly by 2026-07-08. Two consequences: + +- *Never treat a 100-row result as complete.* When a scan returns exactly 100, walk the tail in *date slices*: re-query with =before:<oldest-full-day-seen>= (day resolution), repeat until a page returns fewer than 100, dedupe by message id across slices (the day-resolution boundary overlaps). +- *Never report =resultSizeEstimate= as a count.* It's unreliable — observed stuck at "201" across three different queries whose real union exceeded 300. + +*** Backlog-residue check (every sweep — cheap, mandatory) + +The anchored scan is blind to anything unread from *before* the anchor. After it, run one probe for pre-anchor residue: + +#+begin_src text +mcp__google-docs-personal__listMessages q="is:unread in:inbox before:<anchor-YYYY/MM/DD>" maxResults=5 +#+end_src + +If it returns any messages, surface one loud line in the sweep summary: "Backlog: unread predating the anchor exists (N+ shown; date-slice to inventory)" and offer a backlog sweep. Never fold the residue into a quiet sweep — an anchored "no changes" claim is only true for the window the scan saw. (Added 2026-07-08 after ~300 pre-anchor unread accumulated unseen; the probe returns actual messages, so it works where the estimate lies.) + ** Classify Bias: *trash-leaning* — personal Gmail is high noise volume. diff --git a/claude-templates/.ai/workflows/triage-intake.personal-gmail.org b/claude-templates/.ai/workflows/triage-intake.personal-gmail.org index a7af333..7d1ab4d 100644 --- a/claude-templates/.ai/workflows/triage-intake.personal-gmail.org +++ b/claude-templates/.ai/workflows/triage-intake.personal-gmail.org @@ -25,6 +25,21 @@ mcp__google-docs-personal__listMessages q="is:unread in:inbox after:<anchor-epo ⚠ *Do NOT add =-category:promotions -category:social=.* That filter masked 67 promo+social messages across two runs (2026-05-04, 2026-05-06), both needing a follow-up sweep. Pull the full unfiltered set; the trash-leaning bias in Classify handles promotions and social directly. +⚠ *The MCP caps at =maxResults=100= and exposes NO =pageToken= parameter.* The response carries a =nextPageToken=, but the tool can't consume it, so a pile over 100 is silently truncated — the tail below the cap never gets classified, and every later anchored sweep skips it (it predates the new anchor). This is exactly how a 300+ backlog accumulated invisibly by 2026-07-08. Two consequences: + +- *Never treat a 100-row result as complete.* When a scan returns exactly 100, walk the tail in *date slices*: re-query with =before:<oldest-full-day-seen>= (day resolution), repeat until a page returns fewer than 100, dedupe by message id across slices (the day-resolution boundary overlaps). +- *Never report =resultSizeEstimate= as a count.* It's unreliable — observed stuck at "201" across three different queries whose real union exceeded 300. + +*** Backlog-residue check (every sweep — cheap, mandatory) + +The anchored scan is blind to anything unread from *before* the anchor. After it, run one probe for pre-anchor residue: + +#+begin_src text +mcp__google-docs-personal__listMessages q="is:unread in:inbox before:<anchor-YYYY/MM/DD>" maxResults=5 +#+end_src + +If it returns any messages, surface one loud line in the sweep summary: "Backlog: unread predating the anchor exists (N+ shown; date-slice to inventory)" and offer a backlog sweep. Never fold the residue into a quiet sweep — an anchored "no changes" claim is only true for the window the scan saw. (Added 2026-07-08 after ~300 pre-anchor unread accumulated unseen; the probe returns actual messages, so it works where the estimate lies.) + ** Classify Bias: *trash-leaning* — personal Gmail is high noise volume. |
