Skip to main content
A spec-diff tool reads what the provider published. Monitoring sees your traffic but throws response bodies away. The agent holds both, so it can say things neither can.

Arming it

spec_source accepts an http(s) URL, a local file, or git:<ref>:<path>. The watcher is part of pikopod up, not a separate command, and arms per upstream:

What it does

Every interval it re-fetches the source. Fetches are ETag-gated, and unchanged bytes are never re-normalized. When the document changed, it is diffed against your pin, the contract you imported, with the same checks and the same severity law as pikopod spec-diff. Every finding becomes a declared-drift event with source: declared and a declared:<check-id> kind, alerting on first occurrence because a spec diff is deterministic. A document that fails to fetch or parse is reported, and the watcher keeps its previous state rather than going dark. A spec of more than 32 MiB is refused, never truncated.

The pin never advances on its own

Accepting a declared change is explicit:
--update re-imports from the recorded source (or --spec), keeps the sandbox’s webhook envelope and event bindings, and resets the watcher’s pin.

The join, both directions

Traffic raises a declared finding. A declared change downgrades an observed finding. When the provider’s new spec declares a field, an enum value, a status or an endpoint that traffic then shows for the first time, the observed drift is marked documented and delivered at INFO:
The fingerprint never moves in either direction. Only the level and the detail do.

Health

/healthz carries a spec_watch block per source with the last check, last change, spec version, finding count and last error. pikopod status shows it.
  • Spec diff, the same diff as a CI gate.
  • Spec update, turning traffic evidence into additive spec patches.