molted overrides
Human-in-the-loop overrides
| Command | Description |
|---|---|
molted overrides counts | Get override queue counts |
molted overrides queue | List items in an override queue. Valid queue names: needs_approval, blocked_by_policy, high_risk, spam. |
molted overrides held-messages | List held messages |
molted overrides release | Print the human decision link for a held message. Releasing is human-only (D3), this does not call the API. |
molted overrides reject-held | Print the human decision link for a held message. Rejecting a held message is human-only (D3), this does not call the API. |
molted overrides approve | Print the human decision link for a pending send. Approving is human-only (D3), this does not call the API. |
molted overrides reject-send | Reject a held thread: rejects its pending send approvals and trashes the thread. Human-gated with no own-send exception: once the workspace enforces the human gate it returns 403 human_decision_required with a decisionUrl, even for a send you created. |
molted overrides edit | Print the human decision link for a pending override. Editing is human-only (D3), this does not call the API. |
molted overrides escalate | Escalate a thread: sets its status to escalated and keeps any review queue it is in |
molted overrides not-spam | Mark a thread not-spam: releases it from the spam queue, or from needs_approval when the classifier itself routed it there for a safety verdict. Records spam feedback for the sender. Ungated ONLY for a thread currently in the spam queue that the classifier never held (a plain inbox thread manually reported as spam); gated like a human decision -- prints a decisionUrl and exits non-zero, same as approve/edit/release -- for a needs_approval/high_risk/blocked_by_policy thread, or any safety verdict at all (including one that reads "spam", since it reflects only the latest classified message on the thread). Also refused when a human has taken the thread over, 409 quarantine_verdict on a phishing/malware/abuse/impersonation verdict (release it from Quarantine instead), and 400 for a thread in neither of the two states above. |
molted overrides correct-label | Correct an inbound message's platformLabel (#2277): opt_out, auto_reply, delivery_notice, or none (not any of these). Feedback only: changes no routing, suppression or stored label. Not human-gated. |
molted overrides report-spam | Move a thread to the spam queue and record spam feedback for the sender. |
molted overrides delete-spam | Resolve and trash a thread in the spam queue, confirming the spam verdict. A classifier-flagged spam thread (needs_approval) is gated like reject: 403 human_decision_required once the gate enforces. |
molted overrides spam-stats | Get spam feedback stats: total reports, spam vs not-spam counts, unique domains. |
molted overrides sender-reputation | Get sender reputation stats (spam/not-spam counts, auth pass/fail, score) for a domain. |
molted overrides alerts | Get alert status |
Agent context
Overrides provide a human-in-the-loop approval layer for agent actions. When safety rules or confidence thresholds require human review, messages are held in override queues until a human decides.
Deciding is human-only (D3, epic #1353): approve, edit, release and reject-held do NOT call the API. They print the portal decision link (<portalUrl>/app/decide/<kind>/<id>) and exit non-zero. Share that link with a person on your team -- the CLI cannot make these decisions, even with an operator-scoped key. This is an intentional exception to "all customer features go through the mailbox API": decisions and loosening controls are human-only, reached through the portal/API, and agents only ever get a link.
reject-send still calls the API (POST /v1/agent/override/<threadId>/reject), but that route is gated like approve: it has no own-send (D4) exception, so once the workspace enforces the human gate (the default for new workspaces) it returns 403 human_decision_required with the same kind of link, even for a send you created.
Once a tenant's human gate is in "warn" mode, any call still let through prints a one-line deprecation notice to stderr (Molted-Deprecation: human-gate) -- it will 403 once that tenant enforces.
Check the override queue
molted overrides counts
# → {
# "needs_approval_outbound": 5, # held thread with an outbound message (e.g. a send awaiting OK)
# "needs_approval_inbound": 2, # held thread with only inbound mail
# "blocked_by_policy": 0, # policy engine blocked a send or an inbound message
# "high_risk": 1, # thread anomaly or adversarial routing
# "spam": 3 # reported as spam (report-spam)
# }
# Counts cover unresolved threads in mailboxes the key can manage.
# Spam the classifier flagged sits in needs_approval, not in spam.
# Drill into a queue. Valid queue names (distinct from count fields):
# needs_approval, blocked_by_policy, high_risk, spam
# The two needs_approval_* counts above BOTH surface under the single
# "needs_approval" queue -- use --direction inbound|outbound to filter.
molted overrides queue needs_approval --limit 10
molted overrides queue blocked_by_policy
molted overrides queue high_risk
molted overrides queue spam
molted overrides held-messages --thread-id <id>
# → messages held for a specific threadAsk a human to decide (these print a decisionUrl, they don't decide)
molted overrides approve <threadId>
# → prints the link for a human to approve the pending send
molted overrides release <messageId>
# → prints the link for a human to release the held message
molted overrides reject-held <messageId>
# → prints the link for a human to reject the held message
# (alias: molted overrides reject <messageId>)
molted overrides edit <threadId>
# → prints the link for a human to edit and redirectReject a held thread's pending sends (this one still calls the API)
molted overrides reject-send <threadId> --reason "Wrong template"
# → { "threadId": "...", "status": "resolved", "auditEventId": "...",
# "rejectedApprovalIds": [...] }
# Rejects every pending send approval on the thread and moves the
# thread to the trash. Only while the human gate is off or in warn:
# once it enforces, 403 human_decision_required with a decisionUrl,
# your own send included. 400 if the thread is in no review queue.Escalate to a human
molted overrides escalate <threadId> --reason "Complex legal question" \
--assign-to "legal-team"Spam triage (#1644 -- these call the API directly, no decisionUrl, EXCEPT where noted):
molted overrides not-spam <threadId> --reason "Legitimate sender"
# → clears a thread from the spam queue, OR from needs_approval when the
# classifier itself put it there with a safety verdict (any other
# thread is refused 400). Ungated ONLY for a thread currently in the spam queue that the
# classifier never held (a plain inbox thread a human or agent manually
# reported as spam). Everything else -- needs_approval, high_risk,
# blocked_by_policy, or ANY safety verdict at all, including one that
# reads "spam" -- is gated like a human decision: 403
# human_decision_required with a decisionUrl, same as approve/edit/
# release above. (A thread's safety_verdict reflects only the latest
# classified message on it, so it can't be trusted to tell a corrected
# false positive apart from a still-dangerous thread -- an earlier
# phishing message followed by a later spam-only one flips the whole
# thread's verdict to "spam".) A phishing/malware/abuse/impersonation
# verdict is refused 409 quarantine_verdict (no decisionUrl): only a
# release from Quarantine lets it through. Also refused (403) on a
# thread a human has taken over, regardless of verdict. Records spam feedback on
# success so the sender's reputation improves; after 3+ HUMAN not-spam
# marks for the same address it's auto-added to the sender allow-list
# (never as a whole domain).
molted overrides report-spam <threadId>
# → moves a thread into the spam queue and records spam feedback. Refused
# (400) when the thread is already needs_approval/high_risk/
# blocked_by_policy -- use approve/reject/escalate for those instead.
# Refused (409) on a thread in the trash, (403) on a taken-over thread.
molted overrides delete-spam <threadId>
# → resolves + trashes a thread in the spam queue (confirms spam) and
# records spam feedback. Refused (403) on a taken-over thread.
# Also takes a classifier-flagged spam thread (needs_approval with a
# "spam" verdict), but that is gated like reject: 403
# human_decision_required with a decisionUrl once the gate enforces,
# and 409 while the thread has a pending send approval. Any other
# thread is refused 400.
molted overrides spam-stats
# → { total, spamReports, notSpamReports, uniqueDomains }
molted overrides sender-reputation --domain example.com
# → per-sender rows: spamCount, notSpamCount, authPassCount, ...Correct a platform label (#2277, not human-gated)
molted overrides correct-label <messageId> none
# → says the message's platformLabel was wrong: none (not any label, e.g.
# "not an opt-out"), opt_out, auto_reply or delivery_notice. Feedback
# only: helps Molted learn to sort mail, and changes no routing, no
# suppression and not the platformLabel anyone reads. Act yourself: for
# a real opt-out add a suppression (molted suppressions add). A "none"
# never removes a suppression; removing one is a person's decision.Monitor alerts
molted overrides alerts
# → { checkedAt, overallLevel, conditions: [{ name, value, level,
# description }] }: queue staleness and age, send failures, policy
# blocks, bounce rate, complaints and SLA breaches, each rated
# ok, warning or criticalTypical supervisor agent loop
- molted overrides counts # check queue depth
- molted overrides queue needs_approval # review items
- For each item needing a decision: share its decisionUrl with a human (reject-send is gated too: once the gate enforces it gets 403 like approve)
- A plain inbox thread manually reported as spam: molted overrides not-spam works directly. A classifier false positive still sitting in needs_approval/high_risk/blocked_by_policy: not-spam comes back 403 with a decisionUrl to share -- share it. A phishing/malware/abuse/ impersonation verdict comes back 409 quarantine_verdict instead: a person releases it from Quarantine
- Repeat on interval
Related: molted send, molted threads, molted agents, molted safety
Commands
molted overrides counts
Get override queue counts
molted overrides countsmolted overrides queue
List items in an override queue. Valid queue names: needs_approval, blocked_by_policy, high_risk, spam.
molted overrides queue [options] <queue>| Argument | Description | Required |
|---|---|---|
<queue> | yes |
| Option | Description | Default |
|---|---|---|
--limit <n> | Max items to return (server caps at 50) | 25 |
--offset <n> | Offset for pagination | 0 |
--direction <inbound|outbound> | outbound: threads with an outbound message; inbound: threads without one (the split behind the needs_approval_* counts) |
molted overrides held-messages
List held messages
molted overrides held-messages [options]| Option | Description | Default |
|---|---|---|
--thread-id <id> | Filter by thread ID |
molted overrides release
Print the human decision link for a held message. Releasing is human-only (D3), this does not call the API.
molted overrides release <messageId>| Argument | Description | Required |
|---|---|---|
<messageId> | yes |
molted overrides reject-held
Print the human decision link for a held message. Rejecting a held message is human-only (D3), this does not call the API.
Alias: reject
molted overrides reject-held <messageId>| Argument | Description | Required |
|---|---|---|
<messageId> | yes |
molted overrides approve
Print the human decision link for a pending send. Approving is human-only (D3), this does not call the API.
molted overrides approve <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
molted overrides reject-send
Reject a held thread: rejects its pending send approvals and trashes the thread. Human-gated with no own-send exception: once the workspace enforces the human gate it returns 403 human_decision_required with a decisionUrl, even for a send you created.
molted overrides reject-send [options] <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
| Option | Description | Default |
|---|---|---|
--reason <reason> | Reason for rejection (required) (required) |
molted overrides edit
Print the human decision link for a pending override. Editing is human-only (D3), this does not call the API.
molted overrides edit <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
molted overrides escalate
Escalate a thread: sets its status to escalated and keeps any review queue it is in
molted overrides escalate [options] <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
| Option | Description | Default |
|---|---|---|
--reason <reason> | Reason for escalation (required) (required) | |
--assign-to <user> | Free-form assignee, stored as the thread's assigned agent and escalatedTo |
molted overrides not-spam
Mark a thread not-spam: releases it from the spam queue, or from needs_approval when the classifier itself routed it there for a safety verdict. Records spam feedback for the sender. Ungated ONLY for a thread currently in the spam queue that the classifier never held (a plain inbox thread manually reported as spam); gated like a human decision -- prints a decisionUrl and exits non-zero, same as approve/edit/release -- for a needs_approval/high_risk/blocked_by_policy thread, or any safety verdict at all (including one that reads "spam", since it reflects only the latest classified message on the thread). Also refused when a human has taken the thread over, 409 quarantine_verdict on a phishing/malware/abuse/impersonation verdict (release it from Quarantine instead), and 400 for a thread in neither of the two states above.
molted overrides not-spam [options] <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
| Option | Description | Default |
|---|---|---|
--reason <reason> | Reason for marking not spam |
molted overrides correct-label
Correct an inbound message's platformLabel (#2277): opt_out, auto_reply, delivery_notice, or none (not any of these). Feedback only: changes no routing, suppression or stored label. Not human-gated.
molted overrides correct-label <messageId> <label>| Argument | Description | Required |
|---|---|---|
<messageId> | yes | |
<label> | yes |
molted overrides report-spam
Move a thread to the spam queue and record spam feedback for the sender.
molted overrides report-spam <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
molted overrides delete-spam
Resolve and trash a thread in the spam queue, confirming the spam verdict. A classifier-flagged spam thread (needs_approval) is gated like reject: 403 human_decision_required once the gate enforces.
molted overrides delete-spam <threadId>| Argument | Description | Required |
|---|---|---|
<threadId> | yes |
molted overrides spam-stats
Get spam feedback stats: total reports, spam vs not-spam counts, unique domains.
molted overrides spam-statsmolted overrides sender-reputation
Get sender reputation stats (spam/not-spam counts, auth pass/fail, score) for a domain.
molted overrides sender-reputation [options]| Option | Description | Default |
|---|---|---|
--domain <domain> | Domain to look up (required) (required) |
molted overrides alerts
Get alert status
molted overrides alertsSee CLI overview for global options, credentials and output format.