Time Semantics
Every predicate takes an atTime, and every verdict carries the interval over which its proof answers the question. Proofs witness moments in time, not boolean states.
Why atTime is a parameter
Most location SDKs return "where you are now." The Octet SDK lets you ask "where were you at this specific moment". The answer a verifier cares about is 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.
Three regimes
- 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 in v1.
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. A sprinter exits in seconds. |
The returned validity field on every YES / NO verdict tells you exactly what window applies to this 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 not "how long the verdict will keep being true." It is the interval the underlying proof was good for. The verdict itself has no future. Predict nothing.
Why honest reporting matters
The SDK reports the interval its proof actually 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 honestly withvalidity = [2:59:30, 3:01:30]. - A 5-minute country-level proof can answer a flurry of 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.