Drift detection
Drift detection answers one question continuously: is this integration still behaving the way the evidence says it used to? It works on structural shapes, fingerprints, and descriptions of values, so no payload value ever reaches Seamward, and it distinguishes provider changes from your own deployments using release context.
What a finding looks like
When observed structure disagrees with the expectation, the comparison produces findings with a stable kind and an exact path:
Code example
{ "kind": "type-changed", "path": "$.candidate.salary", "expected": "string", "observed": "number"}The four structural kinds are field-removed (a previously expected field stopped appearing), field-added (a new field appeared), field-renamed (deterministic evidence links one removal and one addition as a rename candidate), and type-changed (a field changed primitive type, which short-circuits deeper comparison at that path). Behavioral findings complement them: status and authentication shifts, median latency shifts, retry anomalies, ordering changes, and missing business outcomes.
Where baselines come from
- Declared contracts. Register an OpenAPI document containing many supported operations, or bind JSON Schema to one explicit operation. Seamward matches each observation to an operation before comparing its shape with that schema. This is the strongest signal because "required" is explicit.
- Established behavior. Without a declared contract, Seamward groups observations by fingerprint and treats the dominant shape as the baseline, diffing minority shapes against it. This needs at least two distinct shapes to say anything, so a brand-new integration reports nothing until evidence accumulates.
- Behavioral windows. Each stable operation identity compares a recent 15-minute receipt window against the prior day, so one slow endpoint cannot distort another. Status and authentication shifts use response codes. Latency analysis requires at least 30 observations in each window and reports when median latency rises by at least 100 ms and 50 percent. Retry analysis requires at least 30 privacy-safe correlated operations in each window and reports when the retry rate reaches 20 percent and rises by at least 15 percentage points. A persisting condition re-records at most hourly rather than flooding the timeline.
Retry analysis groups attempts only when observations carry both a keyed idempotencyKeyHash and its non-secret hashNamespace. A logical operation belongs to the window containing its first server receipt, so a late retry does not become a new operation. Neither hash is copied into finding evidence. Counts, exact medians, retry totals, and sequence transitions are aggregated in the database. The worker reads compact distinct operation identities for contract matching rather than individual traffic envelopes. These aggregates preserve the existing windows and thresholds; medians are not sampled or approximated.
The current release also uses an observed-evidence group when an observation does not match any registered operation. It does not compare that traffic with an unrelated declared schema. See Contracts and operations for import formats, operation identity, and current lifecycle limits.
Telling provider drift from your own deploy
Every observation carries optional release context (service, release, commitSha). When a shape changes at the same moment a new release starts processing traffic, the timeline shows both facts side by side, and the investigation starts from "our deploy changed the mapping" rather than a provider escalation. This is why setting release context is worth the two lines of configuration.
From finding to incident
Analysis runs within seconds of ingestion: the job is enqueued in the same transaction that stores your observations. Findings are deduplicated, then grouped with related evidence into an incident, which is the unit an engineer reviews. A finding is evidence that something changed, not proof of customer impact; the incident timeline is where impact gets established.
Structural comparison uses summaries of retained evidence. Late arrivals update counts and time ranges, and retention removes expired evidence from the baseline. Equal-frequency baselines use fingerprint order for a deterministic tie-break. Very large schema sets can pause structural analysis while behavioral detection and expected-outcome reconciliation continue.
Behavioral capacity
Behavioral analysis also bounds the distinct identity metadata processed in a pass: at most 1,000 identities and 8 MiB, with at most 5,000 new findings per
pass. Overflow records an independent behavioralAnalysis capacity pause without
retrying the job indefinitely or blocking structural analysis and reconciliation.
See capacity recovery.
Missing traffic
Every detector above compares observations that arrived. A provider that stops sending produces nothing to compare, and nothing errors, so ordinary monitoring stays green. Seamward therefore also checks each Live connection on a clock, every five minutes, against that connection's own history.
| Finding | Reported when | Needs |
|---|---|---|
delivery-gap | Nothing has arrived for more than twice the connection's longest normal quiet period, and at least 15 minutes | 30 hours with traffic in the last five weeks |
volume-drop | The last complete hour had at most half the traffic of the same hour in its quietest comparable week | Two earlier weeks, each with at least 30 observations in that hour |
sequence-gap | Sequence positions between the lowest and highest seen in an hour never arrived | Your collector sending a provider sequence |
A finding states both figures, for example no observations for 31 min; the longest normal quiet period is 4 min.
What counts as normal. A connection's longest normal quiet period is the longest pause that has happened at least three times in its history. A pause that recurs, such as overnight or across a weekend, is ordinary for that connection and does not raise a finding. One past outage is not, so it does not make later silences look normal. The two silence checks complement each other: a connection that is quiet every night has a long normal pause, but a silent Monday morning still stands out against previous Monday mornings.
While a baseline is learning. A new connection raises no missing-traffic finding until it has enough history. Its page shows Traffic baseline: Learning with the hours counted so far, then Active.
What you see. Each silence is recorded once, not once per check. A connection that is still quiet appears under Needs attention on the workspace overview and leaves that list as soon as traffic resumes. Missing-traffic findings do not open an incident.
Scheduled feeds can declare how often they run. An overdue run is then reported after one missed interval, with no history required. See the collector guides for Node.js, PHP, and Laravel.
Limits to know:
- Sandbox connections are not checked, because they are often quiet on purpose.
- Volume is counted per connection, not per event type. One event type stopping while others continue on the same connection is not detected.
- Hourly counts are kept for five weeks and contain no evidence, so they outlive your evidence retention period.
- The thresholds are fixed defaults and are not configurable yet.
Value drift
A provider can change what a field means without changing its shape. An amount switches from 1050 to 10.50: a number before and a number after. A date changes from 2026-10-05 to 05/10/2026: a string both times. Every structural check passes, and the data is wrong.
Value drift catches these by comparing a value profile: for each field, a format label, the power of ten of a number, and a length band. The collector computes it inside your process and never sends the value. For each operation, Seamward compares the current and previous hour with the seven days before.
| Finding | Reported when | Example summary |
|---|---|---|
format-changed | A field that had one format now has another | format changed from iso-date to other in 100% of 40 samples |
magnitude-shift | Whole numbers became fractional or the reverse, the sign flipped, or the typical size moved by two or more powers of ten | values were whole numbers; 96% of 50 samples are now fractional |
presence-shift | A field that was filled is now an empty string, an empty list, or zero | empty in 100% of 40 samples; it was empty in 0% of 120 before |
length-shift | A string or a list is far longer or shorter than it has been | length moved from 5-9 to 500-999 characters in 100% of 40 samples |
value-set-changed | A field with few distinct values gained one never seen before, or lost a common one. Needs value hashes | 1 value not seen before appeared in 10 of 40 samples |
How sure it has to be. A comparison needs at least 100 samples in the seven-day baseline and 30 in the current window, and the change must hold for at least 90 percent of the current window. A field that was already mixed, such as a date sent in two formats, does not report. A number has to move two powers of ten, so a counter growing from 9,999 to 10,000 is not a finding. A field counts as newly empty only if it was empty in at most 1 percent of the baseline. A new value needs at least 5 samples and 5 percent of the window.
One cause, one finding. A field that goes blank reports a presence-shift only, not a format and a length change as well. A change is recorded once, however long it lasts, and a different change to the same field is a new finding.
What you see. A value finding appears on the connection with its summary. It does not open an incident.
Limits to know:
- It needs a collector that sends value profiles. The Node.js, PHP, and Laravel collectors do by default.
- A field named in your redaction policy is never profiled, so it is never compared.
- After seven days the new behavior is the baseline, and the finding is not repeated.
- A connection with more than 200 profiled operations has its 200 busiest compared.
- The thresholds are fixed defaults and are not configurable yet.
Boundaries
- No payload value is sent, stored, or compared. Structure is compared as shapes; values are compared as labels and bands that describe them.
- An unexpected field is reported, never silently ignored, but reporting is not judging; harmless additions are yours to dismiss.
- Detection never modifies your integration or contacts the provider.
Next steps
- Catch breaking API and webhook changes: the workflow built on detection.
- Contracts and operations: operation-scoped schemas and version registration.
- Observation envelope: the shape grammar and value profile findings are computed over.
- Redaction: exactly what a value profile contains and how to turn it down.
