# Time Semantics

:::note[In one sentence]

Every predicate takes an `atTime`, and every 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

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:

```swift
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

```mermaid
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]
```

1. **Future**. `atTime > now + 2 s` returns `INDETERMINATE / FUTURE_TIME`. The SDK does not predict.
2. **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.
3. **Historical**. Older. The SDK searches cached proofs for one whose `[from, to]` interval covers `atTime`. 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.

:::caution

**`validity` is not "how long the verdict will keep being true."** It is the interval the underlying proof covers, not a promise about the future.

:::

## 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:00` is answered honestly with `validity = [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 `validity` repeated across the verdicts.

## Where to go next

- [Verdicts](/docs/concepts/verdicts/) for the full `ReasonCode` taxonomy including `STALE_FIX` and `FUTURE_TIME`.
- [Predicates API Reference](/docs/api-reference/predicates/) for the exact signatures.
- [OctetVerdict API Reference](/docs/api-reference/octet-verdict/) for the `validity` field type.
