Verdict rules
After piloop measures a candidate, it asks the verdict rule whether to keep the candidate. piloop gives the rule aCase: the measurements of the candidate, the measurements of its bar, and the metrics that decide. The bar is the
candidate that this one must beat. The rule returns a Judgement: keep, interesting, discard or crash, and
a reason. piloop stores the verdict and the reason on the candidate.
The built-in rule is bootstrap. It keeps a candidate when the primary metric beats the bar with confidence and no
guardrail metric gets too much worse.
Example: keep only a gain of a fixed size
This rule calls the built-in rulebootstrap and changes one thing: a keep whose gain is
below min_gain becomes interesting. min_gain is in the units of the primary metric:
pyproject.toml
piloop_min_gain/__init__.py
The contract
A verdict rule is a pure provider, a subclass ofVerdictRule. Import the types from
piloop.capabilities.
A rule has no error case: it returns a verdict for every case.
The rule also decides the lineage:
bar, raises_bar, head and on_moved read Nodes (a candidate’s id,
verdict, where it was made, Trunk, Branch or Imported, and its means), and each has the built-in behaviour as its
default.
piloop applies the answers: it moves the head, merges, files the seed, and applies the Piloop-Note of a commit.
Built in
bootstrap is the rule of a campaign without [plugins.verdict_rule]. The verdict
describes it.
Stop rules
On each pass, the daemon asks the stop rule of each active campaign whether the campaign goes on, holds, or stops. piloop gives the rule aStopCase: the facts that the rule asked for. The rule returns one
of four answers:
A hold is not a pause. piloop asks the rule again on each pass, and the hold ends when the rule answers
Go. piloop
does not stop a paused campaign, but it holds one.
The built-in rule is limits. It holds the campaign while a fact of hold_at is unknown or at its limit. Else it
stops the campaign at the first of its other limits that the campaign reaches.
Example: end the campaign after a number of keeps
This rule stops the campaign afterkeeps candidates are kept. It calls the built-in rule
limits and adds one limit, so the limits of limits, such as max_hours and hold_at, still apply:
pyproject.toml
piloop_stop_after_keeps/__init__.py
Example: escalate when a keep costs too much
This rule compares the fact thatspend names, since the latest keep, with its value per keep so far. Past
escalate_at times, it answers Escalate once for each keep; past stop_at times, it stops the campaign:
pyproject.toml
piloop_keep_cost/__init__.py
The contract
A stop rule is a pure provider, a subclass ofStopRule. Its fields are its limits and other
parameters. Import the types from piloop.capabilities. Most facts cost database queries on every pass, so piloop
gets only those of reads. piloop status and the briefs join the parts of describe into the progress line:
piloop formats no fact itself.
Go.left says how much of each fact is left before the rule stops the campaign. piloop starts no more runs than
RUNS leaves, and cuts each agent’s timeout where HOURS runs out, so a run that starts just before the stop ends
with it. An agent whose start comes after the rule answers Stop never starts: the pass that stops the campaign
closes its row. check_config refuses a campaign that the rule cannot serve when the file loads: limits refuses a
target on a campaign of more than one track.
A fact is a typed key, Fact[T], that a fact source of the campaign supplies.
case.facts.get(KEEPS) reads one, and case.facts.get(reading('spend')) one that a source reads by name. Every fact
that a rule reads needs a source in the campaign, or piloop refuses the configuration. The facts of the built-in
sources campaign and optimization, from piloop.capabilities, and the ratios over facts that a rule names (spend, the fact of what the
campaign spent; cost, the evaluator’s metric of what one evaluation costs):
Each is None while a term is, or when its count is 0. A rule that reads a ratio asks for the facts of its terms.
A stop that a person requests (
piloop campaign stop) stops the campaign whatever the rule answers, also when the
rule holds it. The closing review of that stop then follows the rule’s while_held
(Spend outside piloop).
Built in
limits is the rule of a campaign without [plugins.stop_rule]. Stop conditions
lists its limits.
Fact sources
A fact source supplies the facts that a stop rule or a section reads.Example: read the spend from a billing endpoint
hold_at = { spend = 1000 } then holds the campaign at that spend.
A fact source is a provider of FACT_SOURCES, a subclass of FactSource. [[facts]] lists a campaign’s sources; a
campaign that does not list them has every installed source that is on by default (ON_BY_DEFAULT): campaign, the
hours and tokens of any campaign, and optimization, its research. A list that adds a source lists those too. Two
sources never supply the same fact.
A Readings source (piloop.plugins.fact_source.kit.readings) is one that the daemon reads every interval seconds,
outside any transaction. It implements names and read, and piloop does the rest: each reading is a fact.read
event on the campaign, its one record. It posts a note at each of its notices, and escalates once when its readings
start to fail.
The contract
The built-in
command source runs a command that writes {"metrics": {"<name>": <value>}} to $PILOOP_RESULT_FILE,
as the evaluate command does.
Spend outside piloop configures it. piloop gives no fact a meaning: a stop rule
or a section names the facts that it reads.