Skip to content

fix(triage): demote awaiting_reply → fyi for confident group/service senders (#210)#389

Merged
99Yash merged 2 commits into
mainfrom
fix/210-sender-kind-awaiting-reply-floor
Jul 3, 2026
Merged

fix(triage): demote awaiting_reply → fyi for confident group/service senders (#210)#389
99Yash merged 2 commits into
mainfrom
fix/210-sender-kind-awaiting-reply-floor

Conversation

@99Yash

@99Yash 99Yash commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Why

The #218 sender-kind user-model projection is now activated in prod (both mailboxes, v2). But its triage consumer is only a soft prompt nudge — it injects a senderKind hint + a rubric sentence, it does not move the category deterministically.

A read-only re-categorize pass (dry-run-triage-recategorize-committed.js) over recent triaged threads, with the projection live, confirmed the gap: confident group/service senders still land in demanding lanes whenever the body reads action-y. The clearest miss:

Net demanding-lane movement was ~flat. The signal resolves correctly; it just doesn't change the tag.

What

A deterministic post-classification floor: when a confident group/service sender's category is awaiting_reply, demote it to fyi. You do not owe a reply to a distribution list or a noreply/bot address, so awaiting_reply from one is definitionally wrong.

Scoped to awaiting_reply only — the zero-bury-risk case (#210 "demote, never bury": fyi stays visible). action_needed/urgent are deliberately left to the model + prompt, because a group/service can legitimately assign the user an action (a ClickUp task actually assigned to them, a real security/payment alert); demoting those safely needs a body-level "directly assigns / @-mentions the user" carve-out — that's the ADR-0066 significance-weighted-category work, not this floor.

  • applySenderKindDemotionFloor (pure) in classify.ts, applied in classifyEmail before the secret override floor so an escalation always has the final word. Tags the model id +kindfloor.
  • senderKindDemotedCategory breadcrumb added to the decision trace (senderExtractionEvent), distinct from the existing person-treatment flag.
  • senderKind is non-null only for a confident group/service (resolveSenderKind gates kind ∈ {group,service} AND confidence ≥ 0.8), so presence is the gate.

Tests

  • 5 unit tests for applySenderKindDemotionFloor (group/service demote; action_needed/urgent/null untouched).
  • 1 classifyEmail orchestration test (awaiting_reply + group senderKind → fyi, +kindfloor, audit.senderKindDemoted).
  • Full triage suite green (115/115); typecheck clean.

Rollout / verification

Takes effect after deploy. To verify: re-run the read-only re-categorize pass and confirm the LinkedIn/awaiting_reply cases now show awaiting_reply → fyi. Related: #218 (activated projection), #353 (todo graveyard), #354 (alarm gate — still needs its own deterministic gate; this floor doesn't touch action_needed).

🤖 Generated with Claude Code

99Yash and others added 2 commits July 3, 2026 15:02
…senders (#210)

The #218 sender-kind projection is now activated in prod, but its consumer is
only a soft prompt nudge — a read-only re-categorize pass showed the classifier
still tags demoted senders (e.g. messages-noreply@linkedin.com, group 0.99) as
`awaiting_reply` whenever the body reads action-y. `awaiting_reply` from a
confident group/service sender is definitionally wrong (you do not write back to
a distribution list or a noreply/bot address), so add a deterministic
post-classification floor that demotes it to `fyi`.

Scoped to `awaiting_reply` only — the zero-bury-risk case (#210 "demote, never
bury"). `action_needed`/`urgent` are left to the model + prompt: a group/service
CAN legitimately assign the user an action, so demoting those needs a body-level
"directly assigns / @-mentions the user" carve-out (ADR-0066), not this floor.

- `applySenderKindDemotionFloor` (pure), applied in `classifyEmail` BEFORE the
  secret override floor so an escalation always wins; tags model id `+kindfloor`.
- Decision trace records `senderKindDemotedCategory` alongside the existing
  person-treatment breadcrumb.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@99Yash 99Yash merged commit 6bb1156 into main Jul 3, 2026
4 checks passed
@99Yash 99Yash deleted the fix/210-sender-kind-awaiting-reply-floor branch July 3, 2026 09:41
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.

1 participant