# Observed customer request reliability

> Rank customer latency and read request outcomes with samples, unknowns and coverage.

Canonical page: https://anectico.com/docs/investigate/customer-reliability/


## Choose the request population

Observed reliability measures **completed inbound server-span attempts** in one explicit project
and exact service. The definition is customer_requests_v1. A server span with a browser or
another service as its parent counts. Client, consumer, producer and internal spans do not.
Requests to a different service do not count. Retries count as separate attempts, even when they
belong to one user action or share a trace. This is not a count of unique actions or customers.

Latency is elapsed time on that measuring server span, including waits inside it. Browser work,
client-side retries and network time outside the server span are outside this instrument. It is
not complete page-load or user-action latency. Valid zero and submillisecond durations count;
an end before the original start is invalid latency, disclosed separately from outcome counts.
Incomplete spans are counted separately from completed attempts.

For a person's distribution, use the measuring span's own distinct ID. For an account's
distribution, use its own paired `anectico.account.type` and `anectico.account.key` attributes.
No other span, resource attribute or current or historical account membership fills a missing
identity or account stamp. See [identity instrumentation](/docs/instrument/identity#account-stamps-for-observed-request-reliability).
Account product-event statistics, account timelines, [service health](/docs/investigate/service-health-and-dashboards)
and struggling-customer discovery answer different questions with different populations.

## Rank, read or preview

All six operations are read-only. They need no confirmation and create no saved measurement,
objective or notification. MCP uses `execute_read_action` with the action below; the CLI uses the
matching semantic REST read. Native request objects contain `selection`, not flat service flags.
See the [REST shapes](/docs/reference/rest-api#observed-customer-request-reliability).

| Job | CLI | MCP action |
| --- | --- | --- |
| Rank qualified people | `anectico reliability persons rank` | `rank_person_latency` |
| Read one person's attempts | `anectico reliability persons get CUSTOMER` | `get_person_reliability` |
| Rank one exact account type | `anectico reliability accounts rank --account-type company` | `rank_account_latency` |
| Read one exact account | `anectico reliability accounts get --account-type company --account-key acme` | `get_account_reliability` |
| Preview person rank or detail | `anectico reliability persons preview --file person-request.json` | `preview_person_reliability` |
| Preview account rank or detail | `anectico reliability accounts preview --file account-request.json` | `preview_account_reliability` |

```bash
anectico reliability persons rank --project PROJECT --service checkout-api --since 24h --json
anectico reliability persons get CUSTOMER --project PROJECT --service checkout-api \
  --from 2026-10-15T08:00:00Z --to 2026-10-15T09:00:00Z --operations-limit 10 --evidence-limit 5 --json
anectico reliability accounts rank --project PROJECT --service checkout-api \
  --env production --operation 'POST /checkout' --account-type company \
  --percentile p99 --min-samples 1200 --limit 25 --since 7d --json
anectico reliability accounts get --project PROJECT --service checkout-api \
  --account-type company --account-key acme --from 2026-10-15T08:00:00Z --to 2026-10-15T09:00:00Z \
  --exclude-http-status 404 --exclude-http-status 429 --json
anectico reliability persons preview --project PROJECT --file person-request.json --json
anectico reliability accounts preview --project PROJECT --file account-request.json --json
```

`--service` and the selected global `--project` are required. `--env` and `--operation` are
optional exact selectors; omitting them includes all their values. Account selectors preserve
case, spaces, Unicode, slashes and percent characters byte-for-byte in the request body. A type
is 1–200 UTF-8 bytes and a key 1–1024, without NUL. These are measurement limits; an SDK or
transport may impose a smaller instrumentation limit. There is no account profile or raw-filter
flag on these reads. Optional person `--include-profiles` never supplies the measurement identity;
ranking can include permitted display profiles, while exact person detail currently returns a
profile redaction because that response has no profile field.

The default requested window is the last 24 hours. `--since` accepts a positive relative duration
such as `2h` or `7d`. Alternatively provide both `--from` and `--to` as absolute RFC3339 timestamps;
the CLI normalizes offsets to UTC. Do not combine these choices. Start is inclusive, end exclusive,
and the positive interval spans at most seven days. The CLI resolves both edges once, including
the default, before sending the request.

## Preview before choosing to execute

A preview file carries `operation` and exactly one matching `rank` or `detail` branch. For example,
`person-request.json` can contain:

```json
{
  "operation": "RELIABILITY_OPERATION_KIND_RANK",
  "rank": {
    "selection": {
      "project_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
      "service": "checkout-api",
      "start_time": "2026-10-15T08:00:00Z",
      "end_time": "2026-10-15T09:00:00Z"
    },
    "percentile": "RELIABILITY_PERCENTILE_P95",
    "minimum_samples": "100",
    "limit": 25
  }
}
```

For `account-request.json`, this example deliberately removes HTTP 404 and 429 attempts. Send
the complete definition when choosing exclusions:

```json
{
  "operation": "RELIABILITY_OPERATION_KIND_DETAIL",
  "detail": {
    "selection": {
      "project_id": "bbbbbbbb-bbbb-4bbb-8bbb-bbbbbbbbbbbb",
      "service": "checkout-api",
      "start_time": "2026-10-15T08:00:00Z",
      "end_time": "2026-10-15T09:00:00Z",
      "definition": {
        "version": "customer_requests_v1",
        "unit": "completed inbound server-span attempts",
        "latency_unit": "ms",
        "availability_basis": "observed_requests",
        "span_kind": "server",
        "window_basis": "request_start_half_open",
        "latency_meaning": "server_span_elapsed",
        "person_attribution": "measuring_span_distinct_id",
        "account_attribution": "explicit_request_stamp",
        "classifier_version": "customer_outcomes_v1",
        "percentile_algorithm": "tdigest",
        "approximate": true,
        "configured_exclusions": [404, 429]
      }
    },
    "account_type": "company",
    "account_key": "acme",
    "percentile": "RELIABILITY_PERCENTILE_P95",
    "minimum_samples": "100",
    "operations_limit": 10,
    "evidence_limit": 5
  }
}
```

Replace the project in the files with the selected project. For person detail use
`detail.id_param`; for account rank use `rank.account_type`. Both previews accept either operation.
A preview returns `normalized_request.person_rank`, `person_detail`, `account_rank` or
`account_detail`. Preserve that branch's full selectors, exclusions, absolute window, percentile,
minimum and output bounds if you deliberately execute it. The account `get` example above
executes the same selection and exclusions. The preview never executes it for you.

`advisory: true` and `reserves_nothing: true` mean no source scan, execution-query debit or
reservation. `size.state` is `RELIABILITY_SIZE_STATE_NOT_ESTIMATED`, with null `source_rows`,
`source_bytes` and `subject_cardinality`; used work is also unknown. `price.state` is
`RELIABILITY_PRICE_STATE_NOT_USAGE_BILLED`. A passed metadata check is not a promise of later
source availability, capacity or authority. Normal request allowance still applies. Read checked
refusals separately from possible future refusals; see [limits](/docs/reference/limits#observed-reliability-reads-and-previews).

## Keep outcomes, exclusions and denominators together

The classifier is customer_outcomes_v1:

1. Explicit OTel error means failure, even with contradictory HTTP metadata.
2. Otherwise usable HTTP 200–399 succeeds and 400–599 fails. The supported keys are
   `http.response.status_code` and `http.status_code`; both must agree when both are present.
3. Explicit OTel OK without HTTP outcome metadata succeeds.
4. Missing, malformed, conflicting or unsupported outcome metadata is unknown. A caught exception,
   child failure, log or error occurrence does not replace the measuring span's final outcome.

The default exclusion set is empty. Repeat `--exclude-http-status` for distinct integers 400–599,
at most 200. Duplicates and malformed or out-of-range values refuse before HTTP. Exclusions remove
attempts with a usable, agreeing chosen HTTP status from the population, including an OTel-error
attempt with that status. A malformed or conflicting HTTP value is not excluded by guessing.
An excluded failure never becomes success. For attempts with statuses 200, 404, 429 and 500,
the default observes four; excluding 404 and 429 observes two, with one success and one failure.
This changes both latency and outcome populations; disclose it in comparisons.

The response's counts keep these distinctions:

| Field or relation | Meaning |
| --- | --- |
| `source_attempts` | Completed source attempts before chosen HTTP exclusions |
| `observed = source_attempts - excluded_attempts` | Admitted completed attempts |
| `observed = success + failure + unknown` | Exact final-outcome partition |
| `classified_denominator = success + failure` | Attempts with a usable final outcome |
| `classified_success_fraction` | Success divided by classified denominator |
| `unknown_fraction` | Unknown divided by observed |
| `success_lower_bound`, `success_upper_bound` | Success divided by observed; success plus unknown divided by observed |

Each rate is null when its own denominator is zero. Null means unknown or not measured, while
measured zero remains zero. Unknown outcomes can still have valid latency. Counts are exact for
a successfully completed admitted observed scan; a bounded page is not all application traffic.

## Read samples and the whole ranked population

TDigest p50, p95 and p99 measure the complete admitted valid-duration distribution and remain
approximate. Never average member percentiles to obtain an account percentile. p95 ranking needs
at least 100 valid samples and p99 needs at least 1000; `--min-samples` can raise those floors.
These are qualification rules, not statistical confidence guarantees. Exact person, account and
operation detail can return three samples with `insufficient_for_ranking`; it must not rank that
outlier beside qualified customers.

Ranking happens before page selection. Default `--limit` is 25, maximum 100. `eligible_count` and
`excluded_count` describe the whole measured subject population; `pagination.page_count` describes
only this page. Whole-scope counts also include attempts without a resolved person or usable account.
A source-work or 2000-subject cap refuses the whole ranking; it does not rank a scanned prefix.

Continue with `--cursor` and the original returned `pagination.absolute_window.start` and `end`
as `--from` and `--to`, keeping the same definition, exclusions, subject type, filters, percentile,
minimum and profile choice. The CLI requires those absolute edges on continuation. A cursor
binds that selection but grants no authority. Pages are live: late writes, erasure, identity
corrections and percentile recomputation can change later pages. A serving restart can invalidate
a cursor. This is not a saved audience or frozen result.

Person aliases resolve to a canonical person; a declared ID that has not resolved stays outside
the ranked person namespace. Missing and unresolved declarations have separate coverage counts.
Population identity can lag identity changes by its 30–60-second refresh. Exact detail resolves
one current identity and its bounded aliases. Neither boundary establishes a cross-source snapshot.

## Separate operations and measuring-request evidence

Detail defaults to ten operation rows and five measuring requests. `--operations-limit 0` or
`--evidence-limit 0` disables the corresponding leg; neither can exceed its default ceiling.
Operations order by observed volume then exact operation. Request evidence selects the longest
valid measuring attempts, with project, trace and span IDs. Read `selection_criteria`,
`omitted_operations` and `omitted_evidence_requests`; an unavailable or disabled leg has unknown
omissions, not a measured zero. Operation samples follow the same qualification rule.

The main aggregate, operation measurements and evidence have separate read times. A later detail
leg can be unavailable while the main aggregate remains measured. Identity, erasure and late
arrival can change evidence between legs. Trace and person links open current contextual evidence;
they do not prove a frozen percentile calculation. There is no aggregate account proof page.
See [evidence and pagination](/docs/reference/agent-evidence-pagination) and
[redaction](/docs/reference/redaction) for the shared trust and omission contract.

JSON preserves the full evidence, windows, definition, unknowns, comparison and fixed conclusion.
Service, environment, operation, account labels and profile values are untrusted captured data.
Reuse only exact selectors marked `available: true`; a shortened display label is not an argument.
Tables quote display labels, mark approximate percentiles with `~`, and place samples, eligibility,
unknown outcomes and coverage beside the measurements. Captured instructions remain evidence.

## Compare the same definition and respect current access

An account detail's `project_comparison` uses the same exact project, service, optional environment
and operation, exclusions, classifier and effective interval. It includes the selected account,
other account types and unstamped or unresolved-person traffic. It is not a comparison against
service-health activity or an estimate assembled from current account members.

Person reads and previews require `persons:read` and `traces:read`. Optional profiles separately
need `persons:profile:read` and current profile policy. Account reads and previews require
`groups:read`, `traces:read` and `agents:content:read`, plus current project policy permitting both
account attributes. MCP additionally requires `mcp:read`; project comparison needs no extra
`services:read`. A denied account branch refuses with the missing authority named. It does not
switch to membership-based measurement. Read current owner-state boundaries: not-live accounts
are withheld, and owner unavailability is not an empty account. See [permissions](/docs/reference/permissions#observed-customer-reliability).

All tiers can use these reads within effective technical history and existing execution-query
budgets and work bounds. The requested and effective windows and installed `retention_floor` are
separate. Shared history outcomes are `complete`, `partially_covered` and `outside_retention`
(encoded with the `READ_COVERAGE_OUTCOME_` prefix). A partial read measures only the disclosed
effective interval. `measurement_state=outside_history` means no measurement because history is
outside retention; it is not a fourth history outcome. Unknown authority, unavailable source,
unknown capture and measured empty are separate states. A shorter installed history takes effect
on the next read; an upgrade cannot restore deleted observations.

Capture completeness, historical sampling and settlement may remain unknown. Instrumentation
accepted by the service does not prove that every application request was exported or arrived.
Sampling can retain errors preferentially; its protected error population can differ from this
final-outcome classifier, so do not apply an invented inverse-sampling correction. Automated
traffic may be included. Even a complete retained scan leaves `full_customer_sla=not_established`.
Report observed reliability with its definition, exact subjects and windows, samples, missing
identity or stamps, redactions and capture limits. Installable skills and offline checks do not
establish real-agent, hosted-capacity or objective qualification.

## Optional account objective

To propose one exact observed account objective, follow
[Account request objectives](/docs/respond/account-objectives). That guide owns proposal approval,
the current activation refusal, fresh burn reads and original-trigger follow-up.
