Skip to content

How decisions are made

Every planned action is resolved to apply, suggest, or suppress. First match wins:

#ConditionOutcome
1Rule disabled, or trigger does not matchskipped silently
2if expression throwsskipped, logged, run continues
3Budget spentbudget_exhausted
4Provider returned nothingno_answers
5Depends on a question that was not askedunknown_question
6Destructive op not in allowDestructivedestructive_not_opted_in
7Executor cannot perform the opunsupported_by_executor
8Named template does not existmissing_template
9confidence < gate.suggestbelow_suggest_threshold
10mode == 'shadow'shadow_mode
11mode == 'suggest', or confidence < gate.autosuggest
12otherwiseapply

Rule confidence

A rule is as trustworthy as its least certain input, so its gate value is the minimum confidence across the questions it depends on — gateOn when given, otherwise the ids its if expression references. Averaging would let one confident answer carry a coin flip.

A rule with neither is unconditional and has confidence 1.

Answer types

TypeValueConfidence
noulprobability 0–1derived as |2p − 1|
choicethe selected optionreported by the model
scorea fractional levelreported by the model

A noul carries no confidence of its own, so Dispatch derives one: 0.5 is maximally uncertain, 0 and 1 maximally certain. That lets one gate expression work across all three types.

Scores stay fractional. A score of 1.6 means the distribution sits between two levels. Rounding it before comparing against >= 2.5 would silently move your threshold.

Suppression is the product

suppressed is not diagnostics. In shadow mode it is the entire output — the list you read to decide whether you trust this. Every entry carries the rule that wanted the action, the reason, and the numbers compared:

  Suppressed
    x label: add needs-repro    [needs-repro] shadow_mode
        Shadow mode decides and logs but writes nothing.

Idempotency

A decision is keyed by sha256(target, item, repo context, question ids, config hash). Two consequences worth knowing:

  • Re-delivering the same event serves the stored decision without a provider request.
  • Editing your config re-triages, because the config hash is an input. Renaming a rule or moving a threshold invalidates cached decisions, as it should.

The mode is deliberately not part of the key, so promoting shadow → auto does not throw away everything Dispatch has already worked out.

MIT licensed.