The eight kinds
The level is graded by what breaks consumers: something removed or retyped is
ERR, a new value is WARN, something purely additive is INFO. A finding the provider’s new spec documents is downgraded to INFO with a note saying so. See Spec watch.
Risk is the same grading as the replay gate sees it: agent replay --ci --fail-on <tier> fails a build only on findings at or above that tier, medium by default, and a documented finding drops one tier.
The smallest example
One letter changes, andif status == "success" quietly stops matching:
Fingerprints
A fingerprint isfp_ plus twelve hex characters of a hash over the upstream, method, template, status class, kind, field, before and after. The same divergence has the same fingerprint however many requests carry it, and a changed diff is a new fingerprint by construction. Presentation details such as the documented note are never part of it, so annotating a finding cannot re-alert it.
From a finding to a test
from-drift pins the contract you integrated against as a scenario pack. It passes while your sandbox still honours that baseline and fails the moment you re-import a spec that adopts the provider’s change, so the break happens on your laptop. See Generated packs.
What is not drift
- Latency. Recorded, never a finding.
- Values of fields you declared volatile. Their presence, type and nullability are still checked. See Volatile fields.
- Anything on a muted template.
- Anything before warmup. See Warmup and baselines.
- A provider answering differently from the sandbox. A refusal the spec never mentions is not a shape change. It is a divergence, compared against the sandbox rather than a baseline, so it needs no warmup.
<data_dir>/events.ndjson in the drift event schema, and pikopod agent incidents --only drift lists them.