Candidates
A candidate is one state of the code, identified by its git tree. Each commit that a worker makes is a candidate. The baseline thatpiloop init measures is the first one.
Because a candidate is a tree, a commit that goes back to a known state is that known candidate, and piloop does not
measure it again. A candidate can have several measurements. Its score is their mean under the current
evaluator.
The head and the bar
The head is the latest kept candidate on the trunk. New runs start from it, unless an idea pins another starting point. Each run is judged against its bar. The bar starts at the base of the run, and moves to each keep that the run makes. For a normal run, the bar is the head. Each keep on the trunk beats the head before it, so the trunk is a chain of improvements.The verdict
The daemon gives each measured candidate one verdict:
The rule, in order:
- No value for the primary metric:
crash. - A guardrail past its
floor:discard. - The bar has no score under the current evaluator:
keep. - The primary metric is not better than the bar:
discard. - The primary metric is better, but its worst case at the
confidencelevel is not above zero:interesting. - A guardrail’s worst case is worse than the bar by more than its
margin:interesting. - Otherwise:
keep.
no-op. The change did
not reach what the evaluate command measures.
Metric roles
- primary: the metric to improve. It must beat the bar with confidence for a
keep. - guardrail: a metric that may get a little worse.
marginis the largest regression from the bar that is allowed, in the metric’s own units.flooris an optional hard limit on the value itself: at least the floor forhigher, at most the floor forlower. - watch: recorded, and never part of the verdict.
piloop.toml moves a floor.
Put every margin and floor in
piloop.toml. A limit that is only in brief.md is a request to the agents. A limit
in piloop.toml is enforced by the daemon.Confidence
When the evaluate command writes per-unit results, the verdict uses a paired bootstrap over the units:- Take the units that the candidate and the bar both report, and the difference of each.
- Resample the units with replacement 4000 times, and sum the differences each time.
- The worst case is the
1 - confidencequantile of these sums. With the defaultconfidence = 0.95, it is the 5th percentile.
aggregate. This is right for a deterministic metric, such as a compressed
size. For a noisy metric, write per-unit results.
When the head moves during a run
Two runs can start from the same head. When the first one keeps, the head moves. If the second one then beats its own bar, it isinteresting, with a reason that starts with keeps against its own bar, but the head moved on.
The daemon then merges the second candidate onto the new head, as a commit with two parents. The merge is a new
candidate of the same run, and the daemon measures and judges it against the new head. If the merge has conflicts,
the daemon files a seed Compose candidate#N onto the head instead.
Override a verdict
Any agent or human can change a verdict and say why:Notes
A result that regressed can still be a good starting point. A note keeps it in view:interesting, with a reason that starts with note:. Each --follow-up files a seed pinned to
the candidate. A note is not a keep, and it does not move a bar. A worker notes its own commit with a
Piloop-Note: <why> trailer in the commit message.