Backed by: @pithy-sh/support. Scopes: support:threads:read · support:threads:reply · support:threads:archive · support:threads:reclassify · support:threads:flag.
One inbox, two intakes
Mail arrives with provenance already decided; feedback is the other intake and needs none. Classification sorts both, and running a support inbox is the capability walkthrough.
Mail claimed on the SMTP envelope recipient, and in-app reports from signed-in users.
Same table, same classifier, same taxonomy, same console — because a support person with two consoles has the whole conversation in neither.
channel rides on the thread and on every message, so one app thread can hold an answer that was mailed and one that was not.
Render the provenance, not a boolean
accountLinkSource | Means |
|---|---|
session | An authenticated request proved it |
email_address | Matched from a From: header nobody proved |
null | The address belongs to nobody with an account |
Triage on the disagreement
declaredCategory is what the submitter chose. category is what the model decided. They never share a column.
Filter on either, independently. Filtering on both asks for the threads where they agree — and they filed it as billing, the model calls it a bug report is the most useful row on the screen.
Three sortable axes from one classification
Category answers what is this. Priority answers how fast. Sentiment answers who is about to churn.
angry and frustrated are the ones worth sorting an inbox by.
With AI off
category is uncategorized forever, and the declared category is the only one anybody stated.
Which is exactly the deployment that made two columns necessary.
Replying
A mailed reply to an app thread is recorded as email — and the submission was minted a message id on the way in, so the customer’s answer threads back rather than opening a new conversation.
Threading is on In-Reply-To and References, never the subject.
What you own
The mail, the database, the bucket, and the inference. No Pithy-operated service in the path.