Documentation
¶
Overview ¶
Package rules holds the rule types, the condition matcher, validation, the evaluation order for one email and YAML import/export. It never calls a model and never touches a mailbox.
Index ¶
Constants ¶
const ( OpEq = "eq" OpNe = "ne" OpIn = "in" OpContains = "contains" OpContainsAny = "contains_any" OpNotContains = "not_contains" OpMatches = "matches" OpGt = "gt" OpLt = "lt" OpExists = "exists" )
Condition operators.
const ( MatchAddress = "address" MatchDomain = "domain" VerdictRoute = "route" VerdictKeep = "keep" VerdictBlock = "block" )
Sender rule match types and verdicts.
const ( ActMove = "move" ActArchive = "archive" ActTrash = "trash" ActJunk = "junk" ActFlag = "flag" ActUnflag = "unflag" ActRead = "read" ActUnread = "unread" ActKeep = "keep" )
Action types, in the order the plan lists them.
const MinTrashConfidence = 0.85
MinTrashConfidence is the lowest threshold an intent-based trash rule may have.
Variables ¶
This section is empty.
Functions ¶
func FolderProblem ¶
FolderProblem says, in a sentence, what is wrong with a folder name a rule would move mail to, or "" when it is fine. It is the check a move action's folder gets.
func MarshalYAML ¶
MarshalYAML writes a rules file in priority order, using the shorthands.
Types ¶
type Cond ¶
type Cond struct {
All []Cond `json:"all,omitempty"`
Any []Cond `json:"any,omitempty"`
Field string `json:"field,omitempty"`
Op string `json:"op,omitempty"`
Value any `json:"value,omitempty"`
// contains filtered or unexported fields
}
Cond is one node of a condition tree: a group ("all" or "any" of its children) or a leaf (field, op, value). The zero value is the empty tree, which always matches.
func (Cond) Match ¶
Match reports whether the email satisfies the tree. now is only used by age_days. A leaf that would not pass validation never matches.
func (Cond) Text ¶
Text renders the tree as one line of plain English, for showing a rule's "unless" part to a model: `from_domain is one of a.com, b.com and (subject contains refund or is_bulk is true)`. The empty tree renders as "".
func (*Cond) UnmarshalJSON ¶
UnmarshalJSON decodes a node strictly (a misspelt key must not turn a leaf into an empty, always-true tree) and compiles its regex once.
type Defaults ¶
type Defaults struct {
DecisionModel string `yaml:"decision_model,omitempty"`
FallbackModel string `yaml:"fallback_model,omitempty"`
MinConfidence *float64 `yaml:"min_confidence,omitempty"`
}
Defaults is the optional "defaults" block. The models are daemon settings, so the importer decides what to do with them; MinConfidence is copied onto every rule that sets none.
type Evaluation ¶
type Evaluation struct {
Final *Result
Candidates []Rule // passing intent rules above the cut-off, in priority order
CutOff *Rule // the default when the decider picks none; may be nil
// contains filtered or unexported fields
}
Evaluation is what Evaluate found. When Final is set the email is settled without a model. Otherwise the caller asks the decider to pick among Candidates and passes its answer to Resolve.
func Evaluate ¶
func Evaluate(e message.Summary, rs []Rule, senders []SenderRule, opt Options) Evaluation
Evaluate runs the evaluation order for one email: sender rules, then the priority walk down to the cut-off rule. It makes no model call.
func (Evaluation) Resolve ¶
func (ev Evaluation) Resolve(ruleID int64, confidence float64) Result
Resolve turns the decider's answer into the final result (step 5). A pick outside the candidates counts as "none of these", for which the cut-off rule applies; when none does, the result keeps the decider's confidence that no rule applies. A pick below its threshold goes to Needs review with no action at all, even when there is a cut-off rule.
type Field ¶
type Field struct {
Name string
Type string // string | boolean | number | pass, fail or none | account id
Ops []string // the operators it accepts
}
Field describes one condition field for whoever writes conditions: the rule composer's prompt is built from this list.
type File ¶
File is a rules YAML document in the PRD shape. The database stays the source of truth; this is import/export only.
type Options ¶
type Options struct {
MinConfidence float64 // threshold for rules that set none
Now time.Time // for age_days
}
Options are the per-run settings Evaluate needs.
type Result ¶
type Result struct {
Stage Stage
RuleID int64 // 0 = no rule; with Review, the rule the decider suggested
RuleVersion int
Confidence float64
Actions []Action // the primary rule's actions, then each stacking rule's
Stacked []int64 // stacking rules whose actions were appended
Review bool // below threshold: take no action, show in Needs review
// SenderRuleID is the sender rule that settled the email (Stage is StageSender); 0 otherwise.
SenderRuleID int64
}
Result is the final outcome for one email.
type Rule ¶
type Rule struct {
ID int64
UserID int64
AccountID int64 // 0 = all accounts
Name string
Said string // the user's original wording; "" when they gave none
Template string // the name of the gallery template it was added from; "" = none
Intent string // plain-English intent for the decider; "" = condition-only
Conditions Cond
Exceptions Cond // "unless"
Actions []Action
Priority int // lower runs first
Stack bool
Model string // per-rule decider override
MinConfidence *float64 // nil = the configured default
Enabled bool
Version int
CreatedAt int64
UpdatedAt int64
}
Rule mirrors one row of the rules table.
type RuleError ¶
type RuleError struct {
N int // the rule's place in the file, from 1
ID string // its id (name) as written
Err *ValidationError
}
RuleError is a problem with one rule of a rules file: which rule, and what is wrong.
type SenderRule ¶
type SenderRule struct {
ID int64
UserID int64
MatchType string // address | domain
Value string // lower-case
RuleID int64 // for route: the rule whose actions apply; 0 otherwise
Verdict string // route | keep | block
Source string // user | learned
Hits int
CreatedAt int64
}
SenderRule mirrors one row of the sender_rules table.
type Stage ¶
type Stage string
Stage says which step produced a result; it is stored in decisions.stage. The pipeline rewrites StageDecider to "fallback" when the fallback model answered, which only it knows.
type ValidationError ¶
ValidationError is a rule problem. Path is the offending key as the API reports it, e.g. "conditions.all[0].op". Message is a sentence for a person, complete without the path: capitalised, ending with a full stop, and naming no field path. Error joins the two for a log or the command line.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string