Filter settings reference
Every setting a filter carries, as the API stores it in the filter’s spec and as the console labels it on the filter’s Settings tab. Each saved change is a new version of the filter. For how to change them, and which changes need a fresh approval, see Change a filter’s settings.
A setting the API refuses names the field by its path below, such as
operating_point.leak_through_rate. A key Sift does not know is refused, not ignored.
General
Section titled “General”| Field | Console label | Type and range | Default |
|---|---|---|---|
name | Name (General › Identity) | Text, 1 to 200 characters | none |
intent | Intent (General, fixed) | Text, 1 to 2,000 characters | none |
filter_id | none | flt_ and 4 to 32 lowercase letters or digits | set by Sift |
version | none | Whole number, 1 or more | set by Sift |
spec_version | none | 2 (1 is read and converted) | 2 |
The intent is fixed once the filter leaves authoring, because the gold set was reviewed against it.
Source
Section titled “Source”Where the filter reads events: one tool of a Kindo integration, called on a schedule. Tool, Watermark field and Id field are fixed after creation.
| Field | Console label | Type and range | Default | Effect |
|---|---|---|---|---|
source.mcp_tool | Tool (fixed) | Text, 1 to 200 characters | none | The integration tool Sift calls. |
source.params | Tool parameters | JSON object | {} | The query the tool is asked. A different query reads a different stream. |
source.watermark_field | Watermark field (fixed) | Dotted path, 1 to 200 characters | none | The field that only increases, which the watermark advances on. |
source.watermark_param | Watermark parameter | Text, up to 100 characters, or empty | empty | The tool parameter that receives the stored watermark. Empty, Sift reads the source unfiltered and discards what it has already seen. |
source.cursor_param | Cursor parameter | Text, up to 100 characters, or empty | empty | The tool parameter that receives the page cursor. |
source.id_field | Id field (fixed) | Dotted path, 1 to 200 characters | none | Each event’s stable identifier, so a retried poll cannot start a second run. |
source.time_field | Event time field | Dotted path, 1 to 200 characters, or empty | empty | Where the event says when it happened (ISO 8601, or epoch seconds or milliseconds). Orders events within one poll; empty, events are ordered by arrival. |
source.poll_interval_s | Poll interval | 30 to 900 seconds | 60 | How often Sift reads the source. After a failure the wait doubles from here, up to an hour. |
Pipeline
Section titled “Pipeline”stages holds at most one stage per slot, keyed by slot. Each stage is the recipe in that
slot and its setting. A filter needs at least one stage in a slot that can filter
(Collapse repeats or Decide). See The pipeline.
| Slot key | Slot | Recipes it takes | Filters | Takes candidates |
|---|---|---|---|---|
guarantee | Always escalate | decision_rules, rule_prefilter | no | no |
collapse | Collapse repeats | dedup_cluster | yes | no |
decide | Decide | text_clf_embed_lr, text_clf_setfit, tabular_gbdt, anomaly_novelty, rule_prefilter | yes | yes |
deliver | Shape delivery | digest | no | no |
A stage
Section titled “A stage”| Field | Console label | Type and range | Default | Effect |
|---|---|---|---|---|
stages.<slot>.id | the recipe’s title; Deciding recipe in Decide | A recipe id the slot takes | none | The recipe in the slot. |
stages.<slot>.params | per recipe, below | Object | the recipe’s defaults | The recipe’s parameters. Unknown keys are refused. |
stages.<slot>.mode | Stage | shadow, active | shadow | How the stage runs; with no stage, the slot is Off. See the table below. |
stages.<slot>.candidates | the slate | List; Decide only | [] | Other recipes measured beside the deciding one. They never filter. |
stages.<slot>.origin | none | copilot, analyzer, operator, default, or none | none | Who put the stage there. |
The Stage control’s words for mode, per slot:
| Slot | No stage | shadow | active |
|---|---|---|---|
| Always escalate | Off | Watching | Escalating |
| Collapse repeats, Decide | Off | Measuring | Filtering |
| Shape delivery | Off | Measuring | Grouping |
A stage in shadow is scored and recorded and changes nothing. Shape delivery can be
active only when target.delivery is event_blob.
A candidate
Section titled “A candidate”| Field | Type and range | Default | Effect |
|---|---|---|---|
id | A Decide recipe, not the deciding one, and not twice | none | The recipe compared. |
params | Object | the recipe’s defaults | Its parameters. |
enabled | true, false | true | false keeps it on record without measuring it. |
origin | copilot, analyzer, operator, default | operator | Who put it on the slate. |
Recipe parameters
Section titled “Recipe parameters”The console draws a control for the parameters that decide what a filter filters and for the lists of event fields. The tables below list those. Each recipe also has further parameters that tune how it learns; they are only in Edit as JSON, their defaults suit most filters, and the API’s schema lists them. See Recipes.
| Recipe id | Console title | Labels needed before training | Operated by |
|---|---|---|---|
dedup_cluster | Collapse repeats | 0 | its own similarity rule |
rule_prefilter | Fixed rule | 0 | its predicate |
decision_rules | Plain-language rules | 0 | its rules; never filters |
text_clf_setfit | Text analysis (small sample) | 50 | a score threshold |
text_clf_embed_lr | Text analysis | 300 | a score threshold |
anomaly_novelty | Anomaly detection | 0 | an hourly budget (top_n_per_hour) |
tabular_gbdt | Structured field analysis | 500 | a score threshold |
digest | Group escalations | 0 | its preset; never filters |
text_clf_setfit can train only where an operator has set up its optional install (see
Install without internet access).
dedup_cluster (Collapse repeats)
Section titled “dedup_cluster (Collapse repeats)”| Param | Console label | Type and range | Default |
|---|---|---|---|
text_fields | Fields compared | List of event fields, at least one | none: required |
similarity_threshold | Similarity | 0.5 to 1.0 | 0.92 |
window_minutes | Window | 1 to 1,440 minutes | 60 |
max_cluster_size | Max cluster size | 2 to 10,000 events | 500 |
Two events are repeats when their text is at least similarity_threshold alike and the
earlier one is inside the window. One group never stands for more than
max_cluster_size events.
text_clf_embed_lr (Text analysis)
Section titled “text_clf_embed_lr (Text analysis)”| Param | Console label | Type and range | Default |
|---|---|---|---|
text_fields | Text fields | List of event fields, at least one | none: required |
text_clf_setfit (Text analysis (small sample))
Section titled “text_clf_setfit (Text analysis (small sample))”| Param | Console label | Type and range | Default |
|---|---|---|---|
text_fields | Text fields | List of event fields, at least one | none: required |
tabular_gbdt (Structured field analysis)
Section titled “tabular_gbdt (Structured field analysis)”| Param | Console label | Type and range | Default |
|---|---|---|---|
numeric_fields | Numeric fields | List of event fields | [] |
categorical_fields | Categorical fields | List of event fields | [] |
At least one numeric or categorical field is required.
anomaly_novelty (Anomaly detection)
Section titled “anomaly_novelty (Anomaly detection)”| Param | Console label | Type and range | Default |
|---|---|---|---|
top_n_per_hour | Events an hour | 1 to 10,000 | 50 |
text_fields | Text fields | List of event fields | [] |
numeric_fields | Numeric fields | List of event fields | [] |
top_n_per_hour escalates the most unusual events each hour and filters the rest. It may
not be above operating_point.max_triggers_per_hour, nor above
operating_point.agent_budget.runs_per_hour when a budget is set.
rule_prefilter (Fixed rule)
Section titled “rule_prefilter (Fixed rule)”| Param | Console label | Type and range | Default |
|---|---|---|---|
combinator | Match | all, any (All conditions, Any condition) | all |
predicates | Conditions | 1 to 50 conditions | none: required |
Each condition:
| Field | Type and range | Default |
|---|---|---|
field_path | Dotted path, 1 to 200 characters | none |
op | See below | none |
value | Text, number, true/false, or a list of text or numbers; omitted for exists | none (required unless op is exists) |
op | Console words |
|---|---|
eq | equals |
ne | does not equal |
gt | greater than |
gte | at least |
lt | less than |
lte | at most |
in | is one of |
not_in | is not one of |
contains | contains |
matches | matches pattern |
exists | exists |
decision_rules (Plain-language rules)
Section titled “decision_rules (Plain-language rules)”The Always escalate stage’s recipe. It needs at least one rule of either kind, and every
rule’s key must be unique across both lists. Plain-language rules need the
decision model.
| Param | Console label | Type and range | Default |
|---|---|---|---|
rules | Plain-language rules | Up to 10 rules | [] |
field_rules | Field rules | Up to 10 rules | [] |
max_rescues_per_hour | Max rescues per hour | 1 to 200 events | 20 |
A plain-language rule:
| Field | Console label | Type and range | Default |
|---|---|---|---|
key | Lowercase letters, digits and _, starting with a letter or digit, up to 40 characters | none | |
name | Name | 1 to 80 characters | none |
question | Question | 1 to 300 characters | none |
reach | Reach | narrow (0.1% of filtered events), normal (0.5%), wide (2%) | normal |
A field rule has key and name as above, plus combinator (Match) and predicates
(1 to 50 conditions), as in rule_prefilter.
digest (Group escalations)
Section titled “digest (Group escalations)”The Shape delivery stage’s recipe. It never filters. Choosing a named preset fills in
its four bundled settings; a different value for any of them is refused unless preset is
custom, which must set all four. The four bundled settings and the last three below are
under Advanced settings.
| Param | Console label | Type and range | Default |
|---|---|---|---|
preset | Grouping | no_delay, storms_only, short_wait, not_urgent, custom | no_delay |
wait_s | Wait | 0 to 3,600 seconds | from the preset |
immediate_per_hour | Runs per hour before grouping | 0 to 10,000 | from the preset |
budget_scope | Budget counts | filter (Whole filter), group (Each group) | from the preset |
max_events | Max events per run | 2 to 50 | from the preset |
group_by | Group by | Up to 3 event fields | [] |
max_chars | Max characters per run | 2,000 to 32,000 | 32000 |
split_rate | Split rate | 0.005 to 0.05 | 0.02 |
| Preset | Console label | wait_s | immediate_per_hour | budget_scope | max_events |
|---|---|---|---|---|---|
no_delay | No added delay | 0 | 0 | filter | 25 |
storms_only | Storms only | 300 | 30 | filter | 25 |
short_wait | Short wait | 300 | 0 | filter | 25 |
not_urgent | Not urgent | 900 | 0 | filter | 10 |
custom | Custom | set by you | set by you | set by you | set by you |
wait_s 0 releases a group with the poll that decided it. Below immediate_per_hour runs
in the past hour, an escalation goes singly; 0 always groups. split_rate is the share of
events that would be grouped and are sent singly instead, so grouping’s effect on verdicts
can be measured. A run’s characters are also capped by SIFT_MAX_TRIGGER_INPUT_CHARS.
Target
Section titled “Target”The agent the filter sends to, and how. See The paired agent and the agent contract.
| Field | Console label | Type and range | Default | Effect |
|---|---|---|---|---|
target.agent_id | Agent id (Delivery) | Text, 1 to 200 characters, or none | none | The Kindo agent’s id. None while the paired agent does not exist yet; nothing is sent until it is set. |
target.delivery | none | event_blob, named_inputs | named_inputs | event_blob sends the whole event as one input, sift_event, to an agent generated for the filter. named_inputs fills an existing agent’s own inputs from input_mapping. |
target.input_mapping | none | Object: agent input name to template | {} | Only with named_inputs, and then required. Each value may use {{event.<field>}} and {{sift.delivery}}, nothing else. The keys must match the agent’s declared inputs exactly. |
target.capacity_runs_per_hour | The agent can take (Delivery › Agent load) | 1 to 1,000,000, or none | none | How many runs an hour the agent can take. Sift compares a stream with it to decide which protections to suggest. It limits nothing by itself, and changing it never needs an approval. None uses the deployment’s default, SIFT_AGENT_DEFAULT_RUNS_PER_HOUR. |
named_inputs needs an agent_id; event_blob must have an empty input_mapping.
Operating point
Section titled “Operating point”| Field | Console label | Type and range | Default | Effect |
|---|---|---|---|---|
operating_point.mode | none | shadow, active | shadow | Whether the filter is filtering. Set by approval and the lifecycle, not typed. |
operating_point.threshold | Threshold (Delivery, fixed) | 0.0 to 1.0 | 0.0 | The score at or above which Decide sends an event. Must be 0.0 in shadow, and 0.0 unless the deciding recipe is operated by a score threshold. Set only by approving one on the threshold screen. |
operating_point.leak_through_rate | Leak-through (%) (Delivery › Volume) | 0.01 to 0.05 (1% to 5%) | 0.03 (3%) | The share of events the filter would filter that are sent anyway, to measure what the filter misses. Never zero. |
operating_point.max_triggers_per_hour | Max escalations per hour (Delivery › Volume) | 1 to 100,000 | 200 | The trigger ceiling: escalations counted in an hour while the filter is active. A grouped run counts once per event in it. |
operating_point.on_alarm | On alarm (General › On alarm) | fall_back (Stop filtering), keep_filtering (Keep filtering), loosen (Filter at a safer point) | fall_back | What an active filter does when a drift alarm fires or it passes the trigger ceiling: return to shadow; keep filtering and raise an alert; or, on drift, move to the safer point (on the ceiling loosen keeps filtering). loosen needs a recipe operated by a score threshold. |
operating_point.safer_threshold | none (set on the threshold screen) | 0.0 to 1.0, below threshold, or empty | empty | The point loosen moves to on a drift alarm, approved with the threshold. Empty under loosen until a threshold is approved, and empty again once Sift has moved the filter there. Lowering it is free; raising it needs an approval or a re-affirmation. |
operating_point.agent_budget | Agent budget (Delivery › Agent load): Off, Hold in a queue, Group the overflow, Record only, Custom | an object, or none | none | The most agent runs this filter starts in a rolling hour, in every state. None is no budget. What it has no room for is never filtered: see The agent budget. Setting one, or keeping more back, needs an approval or a re-affirmation on an active filter; clearing it is free. |
operating_point.agent_budget.runs_per_hour | Runs an hour | 1 to 100,000 | required | The budget. A run of one event and a grouped run each count as one; a re-send counts. It must cover the Always escalate stage’s max_rescues_per_hour plus the measuring sample’s share of the budget (the larger of leak_through_rate and shadow_sample.share), since both are sent before anything else. |
operating_point.agent_budget.overflow | Overflow (under Custom) | hold (Hold in a queue), group (Group the overflow), record_only (Record only) | hold | What happens to an escalation over the budget: it waits in a queue, goes in a grouped run, or is recorded and never sent. group needs whole events to an agent Sift generated at contract 4 or later. |
operating_point.agent_budget.queue_max_events | Queue depth (under Custom) | 1 to 1,000,000 | 24 hours of the budget, at most 1,000,000 | How many escalations may wait. Past it, the lowest-priority one is pushed out. |
operating_point.agent_budget.queue_max_age_s | Longest wait (under Custom) | 900 to 604,800 seconds | 86400 (a day) | How long an escalation may wait before it ages out unsent. |
operating_point.agent_budget.pace | Pace (under Custom) | smooth (Smooth), burst (Burst) | smooth | smooth admits at most a twelfth of the budget per five minutes once half the hour’s budget is used. burst admits until it is spent. |
operating_point.agent_budget.warn_at | Warn at (under Custom) | 0.5 to 0.95 | 0.8 | The share of the budget, or of the queue’s depth or wait, at which Sift warns. |
operating_point.shadow_sample | In shadow, send the agent (Delivery › In shadow): Send everything, A tenth, One in twenty, One in fifty, Custom | an object, or none | none | Sampled shadow: in shadow and proposed, send the agent a sample of the stream instead of every event. None sends every event. An active filter ignores it. Changing it never needs an approval. |
operating_point.shadow_sample.share | Share sent (under Custom) | 0.005 to 0.5 | required | The expected share of events sent to the agent. |
operating_point.shadow_sample.guided | Draw (under Custom): Guided, Uniform | true, false | true | Send events the model scores higher more often. false gives every event the same chance. |
operating_point.shadow_sample.floor | Floor (under Custom) | above 0, up to 1 | 0.3 | Under guidance, no event’s chance falls below floor × share. |
operating_point.shadow_sample.min_positives | Positives before a proposal (under Custom) | 20 to 1,000,000 | 50 | Training proposes no threshold until the sample holds this many events the agent called actionable. |
Acceptance
Section titled “Acceptance”What a trained model must show on the holdout before a threshold can be proposed. See Operating point and approval.
| Field | Console label | Type and range | Default | Effect |
|---|---|---|---|---|
acceptance.posture | Posture (General › Policy) | maximise_savings (Maximise savings), balanced (Balanced), catch_everything (Catch everything), custom (Custom), or none | none | How many extra agent runs you will pay to catch one more actionable event. Picks the proposed point on the frontier. |
acceptance.catch_cost_multiple | Catch-cost multiple (shown with Custom) | 0 or more, or none | set by the posture | The posture as a multiple of what one catch costs on this stream: maximise_savings 0.5, balanced 2.0, catch_everything 10,000. Required with custom; with a named posture it must match. |
acceptance.min_labels | Min labels to train (General › Policy) | 0 to 1,000,000, not below the deciding recipe’s own minimum | 400 | The label floor. |
acceptance.holdout | Holdout (General › Policy) | temporal_last_20pct (Last 20%), temporal_last_30pct (Last 30%) | temporal_last_20pct | The newest share of labels kept out of training to measure the model. |
acceptance.metric | none | recall_at_threshold | recall_at_threshold | The measure a point is judged on. |
acceptance.min_value | none | above 0, up to 1.0 | 0.99 | The recall bar, used only when posture is none (a filter saved before postures). |
Because tabular_gbdt needs 500 labels, a filter deciding with it must raise
acceptance.min_labels to at least 500.
The alarm levels Sift watches a running filter against, and when it retrains. Collapse alarms appear only on a filter with a Collapse repeats stage. See How Sift measures a filter.
| Field | Console label | Type and range | Default | Effect |
|---|---|---|---|---|
drift.firing_rate_alarm_pct | Escalation change (%) (General › Monitoring) | 1 to 100 (percent) | 50 | A relative change in the share of events escalated, against the window before’s share, that raises a drift alarm. |
drift.score_shift_alarm_sd | Score-shift alarm (General › Monitoring) | above 0, up to 5 | 0.15 | How far the deciding model’s average score may move against the window before, relative to how spread out that window’s scores were. Lower is more sensitive. |
drift.feature_psi_alarm | Feature drift alarm (General › Monitoring) | 0.05 to 1.0 | 0.25 | How much the values of the fields the recipe reads may change, week over week, before a drift alarm (0.25 is a large change). The field that changed most is the one judged. Lower is more sensitive. |
drift.retrain_schedule | Retrain schedule (General › Monitoring) | daily, weekly, monthly, never | weekly | How often Sift retrains the filter on its own. |
drift.collapse_compression_shift | Compression shift (General › Collapse alarms) | 0.05 to 0.5 | 0.15 | How far the share of events Collapse folds away may move between the last day and the week before, in absolute points, before it warns. |
drift.collapse_runaway_share | Runaway share (General › Collapse alarms) | 0.2 to 0.9 | 0.5 | The share of a day’s events one group may hold before it is read as a false merge. |