# Identity correction and instrumentation doctor

> Inspect identity links, separate mistaken aliases, and diagnose trace and log visibility.

Canonical page: https://anectico.com/docs/instrument/diagnostics/


## Correct an identity link

Open **Customers → a person → Identity links**, choose the identifier and select
**Preview separation**. The preview shows the current owner, number of linked
identifiers, recent mapping history and the exact effects. Owners and administrators
can select a reason and choose **Separate identity**. API keys require `persons:correct`;
preview/history requires `persons:read`. SDK `analytics:write` cannot correct identities.

Separation creates a new anonymous person with no properties and moves one alias to it.
The original person must retain at least one other alias. Existing profile properties
and their mutation history remain on the original person because their alias ownership
is unknown. Future property updates sent with the separated alias populate its new profile.
Both historical and future signals carrying that alias resolve to the new person after
the asynchronous identity mirror and dictionary update. Stored aggregates and account
memberships are not rewritten. This is an all-time alias separation, not a date-based
split of a recycled identifier.

The separated person blocks automatic identification links in both directions. Calling
identify with the separated device as the anonymous ID will not promote or merge it into
another user. Calling identify with it as the stable ID does not attach another alias.
Use a new anonymous identifier after logout/shared-device changes in your SDK.
There is no automatic undo or manual reattachment operation in this version.

History records new assignments, automatic repoints, and operator corrections with the
operator's user/API-key identifier and a fixed reason. It returns the latest 50 changes.
`baseline_unknown` describes an existing assignment at migration time; it does not claim
to explain older merges. History is removed when the owning alias is erased, including
organization/project deletion. It contains no profile property values.

A revision binds the preview to the source profile and its alias mappings. Concurrent
changes cause HTTP 409 / gRPC Aborted: reload the preview and review it again. If a request
times out, inspect history before retrying; reusing an applied revision cannot create a
second person. Do not treat a conflict as proof that the earlier request failed.

CLI (uses the active `--project`):

```bash
anectico persons correct-identity 'device-id'
anectico persons correct-identity 'device-id' --apply --revision '<reviewed-revision>' --reason shared_device
```

REST: `GET /api/v1/identity/corrections/preview?project_id=…&distinct_id=…`, then
`POST /api/v1/identity/corrections?project_id=…` with `distinct_id`, `revision` and
`reason` (`shared_device`, `recycled_id`, or `incorrect_identify`). The server derives
organization and actor from the credential; project-scoped credentials cannot select
another project.

MCP: use `execute_read_action` with `preview_identity_correction`, then the write gateway's
`correct_identity` action. The write gateway requires its normal confirmation token in
addition to the reviewed revision. These actions belong to the admin profile.

## Find out why data is missing

Open **Check instrumentation** from the telemetry setup checklist, or visit
`/configure/instrumentation`. Select a project and run checks. The doctor queries traces
and logs in the last 15 minutes. Optionally supply an environment and a trace ID produced
by your own application. Generate a trace with your installed SDK, ensure it is sampled,
flush the exporter and copy its 32-character hexadecimal trace ID into the doctor.
Uppercase and lowercase hexadecimal IDs are accepted and searched in canonical lowercase.

The results distinguish:

- **visible**: at least one matching record reached queryable storage; this does not prove complete delivery.
- **filtered**: a search without the environment filter found traces, while a recheck with it found none. Inspect the returned traces' environments; the queries are separate snapshots and data can change between them.
- **withheld**: the credential cannot read the signal; presence was not checked.
- **unavailable**: the query failed; there is no missing-data conclusion.
- **unknown**: no matching record, or the relevant evidence is not available.

The doctor cannot currently observe your SDK configuration, export acceptance receipts,
queue checkpoints, sampling decisions or retention outcomes. It explains these limits
and provides next actions rather than diagnosing absence as data loss. The general check
covers traces and logs; journey mode additionally checks errors, events and optional replay.
Metrics are not checked. It never sends test telemetry automatically.

CLI: `anectico doctor instrumentation [--trace-id ID] [--environment production]`.
REST: `GET /api/v1/instrumentation/doctor?project_id=…`; optional `trace_id`, `environment`,
`start_time` and `end_time` (RFC3339, positive window of at most seven days). The response
includes the actual project, event-time window, check time and explicit partial status.
MCP: the `instrumentation_doctor` read action is available in investigate/admin profiles.

The entry requires `query:read`. Query independently enforces `traces:read` and `logs:read`;
no elevated credential is used to bypass missing signal permissions. Selecting another
project with a project-scoped key is refused.

## Verify a customer story

Follow [Verify your setup](/docs/start/verify-setup) to create a controlled sample.
The same endpoint and MCP action accept `person`, `event_name`, `browser_service`,
`backend_service` and `expect_replay`. Supply all four string fields plus `trace_id`
to request journey verification. Service names must differ. REST/MCP require replay
only when `expect_replay=true`; REST rejects empty, malformed or repeated
`expect_replay` values; the CLI enables it by default when `--person` is set.

The response adds `journey_verified`, canonical `person_id`, the observed `issue_id`
and individual `journey_*` checks. A verified journey can still have `partial=true`:
SDK configuration, sampling, queue lag and retention attribution remain unknown.
The report is assembled from bounded reads, not an atomic snapshot. Concurrent
identity corrections and arriving events can change later results.

Timeline reads stay pinned to the initially resolved person and only accept aliases
from that profile. The named event and replay must match the same linked browser
session. Start a fresh replay session inside the selected window for this controlled
test: a replay that started before the window is not verified by these timeline reads.

Journey verification also needs `persons:profile:read`, `persons:read`, `errors:read`, `analytics:read` and,
when replay is requested, `replay:read`, in addition to `query:read` and `traces:read`.
Log access is optional for the connected story; its separate check remains withheld
when `logs:read` is absent. No missing scope is bypassed.
