Time Semantics
Every predicate takes an atTime, and every YES or NO verdict carries the interval over which its proof answers the question. A proof attests to a moment in time, not an ongoing state.
The atTime parameter
atTime sets the moment the predicate asks about. A verifier usually cares about the moment of a business event: when the order was placed, when the auth attempt happened, when the camera was triggered.
atTime defaults to "now", so most calls look like:
let v = await sdk.loc.isWithin(region: .country(isoCode: "US"), atTime: Date())
You can also pass any past instant within the SDK's cached-proof window. The SDK will search for a proof whose validity covers it.
How atTime is resolved
flowchart LR
A[atTime in the future?] -->|yes, >2s| F[INDETERMINATE / FUTURE_TIME]
A -->|no| B[atTime near now?]
B -->|±2s| L[Live query: use ring buffer<br/>or trigger a fresh proof]
B -->|older| H[Historical query: search<br/>cached proofs for a covering one]
L --> R[Result]
H -->|covered| R
H -->|not covered| S[INDETERMINATE / STALE_FIX]
- Future.
atTime > now + 2 sreturnsINDETERMINATE / FUTURE_TIME. The SDK does not predict. - Live. Within ±2 s of
now. The SDK searches its ring buffer at the right resolution. On a miss, it can trigger a fresh proof. - Historical. Older. The SDK searches cached proofs for one whose
[from, to]interval coversatTime. On a miss,INDETERMINATE / STALE_FIX.
The 2 s tolerance is the SDK's internal clock-skew budget. It is not configurable.
Validity intervals
A LocationProof is good for a window around its fix time, not forever. The SDK's per-resolution windows reflect how quickly a moving user can leave the claimed region:
| Disclosure level | Window (± from fix) | Reasoning |
|---|---|---|
country |
5 min | A commercial flight is the fastest realistic country-change vector. |
subdivision |
3 min | Margin against transitions across small US states. |
city |
1 min | A 5 km city radius is crossed in ~3 min at 100 km/h. |
continuousArea / continuousVolume |
30 s | Hundred-meter scales, which a person running can cross in seconds. |
The validity field on every YES / NO verdict gives the window that applies to that proof. Do not assume a flat 30 s for everything. If your business rule needs a tighter time bound than validity provides, reject the verdict.
validity is the interval the underlying proof covers. It does not say how long the verdict will stay true.
Validity in practice
The SDK reports the interval its proof answers, not the moment of the predicate call. That distinction matters when:
- A user asks "where was I at 3:00:00 pm" and the proof was fixed at 3:00:30 pm. With a 60 s window, that proof covers 2:59:30 to 3:01:30. So
atTime = 3:00:00is answered withvalidity = [2:59:30, 3:01:30]. - A 5-minute country-level proof can answer many country-level predicate calls without regenerating. The verifier sees one proof. The integrator sees the same
validityrepeated across the verdicts.
Where to go next
- Verdicts for the full
ReasonCodetaxonomy includingSTALE_FIXandFUTURE_TIME. - Predicates API Reference for the exact signatures.
- OctetVerdict API Reference for the
validityfield type.