# Investigate with Customer Detective

> Ask production questions and verify grounded answers against cited telemetry.

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


Customer Detective is Anectico's hosted investigation assistant. It gathers relevant telemetry, explains
what it found, and links claims back to evidence in your project.

## Start from the right place

Use **Investigate** for an organization or project question. Use **Explain this person** on a customer
or the Detective action on an Issue when you already know the investigation anchor.
API and agent clients can also anchor an investigation to one customer agent run or one incident
case file. The run investigation explains its steps, errors, LLM cost, served customer, and what
the run affected outside itself; the incident investigation assesses lifecycle state, attached
alerts or Issues, affected customers, and the response timeline.

The current project, environment, and time range limit what Detective can retrieve.
Investigations started from a customer, Issue, or account keep that active project on
their saved anchor. The **Recent investigations** list on Investigate shows saved
investigations of every anchor type from the active project, newest first, so a
customer investigation remains available after you leave the customer page.
If no available project is selected, **Needs attention** and **Recent investigations** ask you to
select one. Empty-result messages appear only after that project's data has loaded successfully.

## Investigate an exact saved audience

MCP, CLI and REST can investigate a retained saved audience generation. Select the project,
cohort UUID and exact generation, plus an explicit evidence start and end. The evidence window
is independent of the original analytics measurement: it does not recalculate membership.
Changing the generation or window starts a different investigation.

In the dashboard, open **Cohorts → Saved audiences → Inspect**. Under **Investigate with
Customer Detective**, choose the evidence start and end in UTC, then **Review investigation**.
Check the fixed generation, full saved population and inclusive dates before selecting
**Investigate this audience**. Starting uses your plan's Detective allowance; reviewing the
selection does not start a model call. Previous investigations are filtered to that exact
generation and window. Follow-up questions retain the same population and dates.

The answer separates saved people, selected people, successfully examined people, unavailable
members and returned timeline items. A source citation opens the exact saved generation under
your current access. A person citation opens that person's timeline with the investigation's
project and dates; other profile summaries retain their own scope. Invalid or wrong-project
evidence links show an explicit refusal instead of silently using the dashboard's time range.
An expired generation hides its investigation panel. Source access refusals hide previously
loaded history rows; refresh the audience list to check what remains available.

For MCP, call `investigate` with `anchor: "audience"`, `cohort_id`, `audience_generation`
as a decimal **string**, and `since` / `until` as RFC3339 timestamps. Supply `project_id` unless
the credential already selects it; an explicit project mismatch is refused. Then use
`get_investigation` with the returned ID to retrieve the answer.

```bash
anectico investigate start --anchor-kind audience --anchor-ref "$COHORT_ID" \
  --audience-generation 2 --project "$PROJECT_ID" \
  --since 2026-09-12T08:00:00Z --until 2026-09-12T09:00:00Z \
  "What happened during checkout for these people?"
```

`investigate list` accepts the same audience flags to find history for that exact selection.
`investigate get`, `watch`, `continue` and `cancel` use the returned investigation ID.
REST Start uses `anchor.audience` with `project_id`, `cohort_id`, `generation`, `start` and `end`;
REST List uses `anchor_kind=audience` and URL-encoded audience JSON in `anchor_ref`.
Times are inclusive, after the Unix epoch, at millisecond precision and no more than 90 days apart.

The answer includes an Anectico-authored **Saved population and evidence coverage** section.
It preserves the full saved member count separately from selected, successfully examined and
unavailable members, and identifies the source result, snapshot and selection. Detective selects
at most the first 20 canonical person IDs and reads up to 30 newest timeline items per person.
Long timeline text is shortened to keep every inspected member within the evidence budget;
these omissions are disclosed. When any investigation gathers more evidence than the budget holds,
the items left out are chosen by relevance to your question when the ranking model is available,
and in a fixed order otherwise; either way the answer discloses what it did not read. This deterministic subset is **not a representative sample**. Do not extrapolate its behavior to
the full audience or treat the saved count as the number of affected people. Source completeness
remains unknown, including when no activity is returned or history is outside current retention.

This anchor uses basic timeline summaries. It does not send event property bags, person profile
bags, replay DOM or model transcripts to the provider. Follow-up questions keep the same
population and window; they do not expand to unrelated people named in the question.

The requester needs `investigations:run`, `analytics:read`, `persons:read` and the saved source's
current permissions. Anectico rechecks the exact source for starts, retries, cached answers,
follow-ups, history, watch updates and cancellation. Expired, erased or no-longer-authorized
source evidence makes the saved investigation unavailable. Detached work retains the original
credential's ceiling and cannot use an internal account to bypass expiry or revocation.
The normal investigation plan allowance and configured model provider are also required.

## Ask a bounded question

For a product question such as “Where does checkout lose people?”, measure the outcome first using
the [product analytics workflow](/docs/investigate/product-analytics). An external agent can execute a typed query
with `query_product_analytics`, inspect its coverage and whole-window sample or denominator, then
use `list_analytics_participants` and `get_analytics_contribution` to follow the exact result into
person and event evidence. Preserve the result, snapshot and selection references in citations.
Unknown coverage or an unavailable denominator is a limitation, not a measured zero or rate.

Save a complete selection as an audience before result expiry when a later investigation needs
that membership. The hosted audience investigation examines bounded timelines; its saved member
count and inspected subset do not constitute a conversion or retention measurement. Detective can
recommend a measurement as a next step, but does not execute analytics queries from model prose.
Use saved membership as a population filter; the native query determines the eligible denominator,
even when every saved member was examined.
For later measurement, explicitly prepare the original source, run its reviewed template, then
compare the two result IDs as described in [remeasurement](/docs/investigate/product-analytics#remeasure-an-explicit-original-result).
An expired original metric remains unavailable even when its saved membership survives.

To check recovery of a failed business operation, use `customer_recovery` through MCP with
`match_operation: true`, or `anectico issues recovery --match-operation` with explicit project,
baseline and observation windows, issue groups and success event. Match the canonical person,
logical operation and event-time account. Another successful order or account does not recover
the original failure; missing activity is **not observed**. Later errors or unmatched retries
can invalidate a recovery claim. See [operation outcomes](/docs/investigate/customer-experience#build-a-release-customer-impact-brief)
for release-scoped matching and source-completeness limits. An improved metric alone does not
prove individual recovery or causation.

Good questions include a customer, symptom, journey, or time boundary:

- “Why did checkout failures increase after the last release?”
- “What happened to buyer@acme.example this morning?”
- “Are errors, latency, and logs pointing to the same service?”
- “Which customers are driving LLM spend this week, and why?”
- “Why did this customer agent run fail, and which step caused it?”
- “What is the impact of this incident, and what changed during the response?”

Avoid prompts such as “Is everything okay?” They force a broad search and produce a less useful
answer.

For a project question, Detective searches the selected window and also checks the most recent
matching Issue as a bounded fallback. When an Issue has a trace, Detective follows that exact trace
to retrieve its spans, trace-linked logs (including structured attributes such as a request ID), and
the service metrics recorded around the occurrence. This lets a request- or customer-specific
question stay grounded even when the Issue message does not contain the words used in the prompt.

## What an agent-run investigation examines

An agent run is one trace, so a run investigation follows that exact trace outward as well as
downward. Alongside the run's own steps, cost, outcome and served customer, it retrieves:

- **the Issues the run produced** — the Issues that at least one occurrence of this run's own
  trace belongs to, most recently seen first. This is the difference between *"a step returned an
  error"* and *"this run is one instance of the Issue your team is already tracking"*, and each one
  is a citation you can open. Requires `search:read`;
- **the log lines carrying the run's trace**, with their structured attributes, and the service
  metrics recorded across the run's own start-to-finish window. Also `search:read`; and
- **the session the run was served in** — the errors the customer's browser recorded and the
  product events they triggered while the run executed. Requires `replay:content:read`; a session
  replay is never itself shown to a model.

The window is the run's own duration plus a short margin either side, so a busy project does not
dilute one run's evidence with unrelated activity, and the Issue list is capped at the few most
recent — a run whose trace touches more than a handful of distinct Issues is itself the finding.

Each of these is gathered only if your credential could read it directly. Anything your credential
could not is named in the answer rather than quietly omitted, so a run with no correlated Issues
never reads the same as a run whose Issues you were not permitted to see — and a run whose
transcript your credential may not read never reads the same as a run that recorded none.

## Ask whether a recorded run reproduces

On an agent-run investigation, ask **“Replay this run and tell me whether it reproduces”** when the
answer depends on reproduction. Detective then replays that run's recorded sequence in a closed
sandbox. It follows the steps that were actually recorded, in their recorded order; it does not add
a branch, remove a step, shorten the run, call a live model, or invent an alternative scenario.
Calls that could have an effect are answered by the sandbox and are named as stubbed evidence.

The answer ends with an Anectico-authored `## Replay evidence` section. It identifies the recorded
run and sandbox plan, says whether the replay matched the recorded sequence exactly, and reports
the recorded, missing, and stubbed tool-result counts. The section is a citation, not a model-written
summary, so its run identity and reproduction result remain inspectable.

Replay is explicit rather than automatic. An ordinary agent-run investigation does not spend a
replay attempt, and requesting one appears in the investigation's progress history. Each
investigation can make one replay attempt. A second request is refused with that limit in the
answer; it is never quietly skipped.

The caller must hold `evals:read` and `agents:content:read`. Anectico checks the requesting
credential even though the investigation uses its own internal credentials to gather evidence.
The project's content settings must also permit the recorded transcript and tool arguments both to
be shown to a model and to be read. If permission is missing, a content setting refuses either use,
the settings cannot be confirmed, or replay is temporarily unavailable, the same `## Replay
evidence` section says that no replay result was available and why. The rest of the investigation
can still complete from its other evidence.

## Read citations as part of the answer

Each important claim should cite an Issue, trace, log set, metric, replay, customer, account, agent
run, incident case file, incident timeline, attached alert, or attached anomaly. Incident and timeline
citations open the case file; alert and anomaly citations open the matching item in its feed. Open the
citation and confirm:

- it belongs to the expected project and environment;
- its timestamp is inside the investigation window; and
- the evidence actually supports the conclusion.

For a customer investigation, a log is associated with a trace only when both appear as
retrieved evidence with the same trace ID. Detective exposes separate log and trace
citations for that exact relationship. A nearby log with similar wording is not treated
as trace evidence.

Only evidence validated by Anectico becomes a clickable citation. Unresolved or truncated
citation tokens are hidden without removing the surrounding explanation; they are never
shown as raw identifiers or presented as evidence.

Treat release timing carefully: “after the rollout” establishes sequence, not cause.
Detective labels a rollout attribution as **Inference** unless the cited evidence states
the mechanism that connected that release to the failure.

Detective helps assemble evidence; it does not replace engineering judgment.

## Ask follow-up questions

Keep follow-ups within the same investigation when they depend on earlier context. Start a new
investigation when changing project, environment, customer, or incident.

For other anchor types, a follow-up steers what Detective retrieves. Name the thing you want examined and it is fetched
into the evidence for that turn, ahead of the anchor's own signals:

- a **trace id** retrieves that trace and its spans;
- a **customer identifier** — an email or a customer id — retrieves that person's profile, so you
  can ask how a second customer compares with the one under investigation;
- a **quoted phrase** — `"payment declined"` — is searched verbatim across logs, traces and metrics
  in the anchor's project, and other key words in the question are searched the same way.

Each retrieval is subject to the same permissions and content settings as the rest of the
investigation, and anything withheld is disclosed the same way (see below). An identifier that
does not exist adds nothing and is not reported as a failure. The opening question of a
customer, Issue, account, run or incident investigation examines the anchor itself; a project
question is retrieved from its own words from the start.

If two clients start the same investigation or submit the same follow-up at the same time, Anectico
accepts exactly one. A duplicate Start receives the accepted investigation id so it can resume
that result; a duplicate follow-up receives an in-progress response and can retry after the
accepted turn finishes. Neither path creates a duplicate answer or consumes a second
investigation from the plan allowance.

The dashboard keeps a long-running investigation session active when its short-lived access token
expires. If expiry happens before a new opening or follow-up stream starts, Anectico rotates the
HttpOnly refresh credential and retries that request once; the prior turn remains visible and the
follow-up is not duplicated.

## When an investigation is refused

Two refusals look similar and mean opposite things, so they are reported as different
codes and different HTTP statuses. Branch on the code, not on the wording.

| Response | `error` | What it means | What to do |
|---|---|---|---|
| `402 Payment Required` | `plan_upgrade_required` | Your plan does not include hosted investigations. | Upgrade. Retrying cannot succeed — nothing resets. `details.required_plan` names the plan that includes them. |
| `429 Too Many Requests` | `rate_limited` | Your plan includes them, but this period's allowance or spend cap is used up. | Wait. The message names the limit and when it resets. |

An automated client must not retry a `402`: the same request is refused identically
every time until the plan changes.

## Stop and resume a long-running answer

Select **Stop live view** to stop receiving the current streamed answer in the browser. If Anectico has
already confirmed the investigation, server-side production continues and is saved exactly once;
the partial text is labeled **Incomplete answer** and must not be treated as a conclusion.

Select **View result** to reconnect to that same saved turn. Anectico polls the existing investigation
instead of asking the question again, so this action does not create a duplicate turn or a second
AI usage charge. Reloading a linked Investigate page resumes the same way. If the live view stopped
before Anectico confirmed a durable investigation, the dashboard does not guess at an older turn;
**Start again** creates a new request.

## Cancel an investigation you no longer need

Stopping the live view leaves the answer being produced. To stop the work itself, cancel the
investigation. It settles in the canceled state and keeps no conclusion; the turn stays in the
history, labeled canceled, so the record of what was asked survives. Canceling the same
investigation twice reports the same settled result rather than failing, and an investigation that
has already finished or already failed cannot be canceled — there is nothing left to stop. Any
open live-answer stream ends with a canceled outcome rather than reporting an internal failure.

## Follow progress across a dropped connection

Progress can be followed as a live stream of lifecycle updates — a turn started, the stage it
reached, and how it settled. That stream is resumable: each update carries a position, and a client
that reconnects with the last position it received continues exactly there, with no repeats and no
gap. Nothing is silently skipped, and a position that is no longer usable is refused outright
rather than being quietly reinterpreted as somewhere else — reload the investigation and resume
from the position it reports.

The progress stream never repeats the answer text. Read the answer itself from the investigation,
which always holds the current durable result.

## What Detective may send to a model

Detective reasons over your telemetry by showing it to a model, so some of what it gathers leaves
your project. Two independent rules decide what, and the first of them has two halves:

- **Your permissions** decide what Detective gathers at all. Evidence your credential could not read
  directly is not gathered, and the answer ends with a `## Not examined` section naming it. See
  [Permissions](/docs/reference/permissions).
- **Your permissions on recorded content** are asked separately. Session content, agent transcripts
  and customer profile properties each need their own permission, over and above the permission to
  read the signal carrying them. When your credential holds the signal but not the content, the
  answer ends with a `## Withheld as sensitive content` section naming what was left out. This is
  the disclosure that matters most, because it is the one you cannot see: the investigation above it
  is complete — the run, its outcome, its cost, its correlated Issues, all cited — with only the
  content missing.
- **Your project's content policy** decides whether recorded content — an agent run's verbatim
  messages, a customer's profile label — may be sent to a model at all, at the `judge_transfer`
  boundary (the policy's **Sent to a model** gate). Content it does not permit is left out for every
  caller, however broadly scoped, and the answer ends with a separate `## Withheld by policy` section
  naming it.
- **An unavailable read** is disclosed under `## Unavailable evidence`. This says some evidence in
  the named source family could not be read or resolved; it does not say the source was empty, and
  it does not erase successfully gathered evidence from the same family.
- **The evidence limit** is disclosed under `## Omitted by evidence limit`. This says some evidence
  was gathered but left out of the model input so the retained evidence must not be treated as
  exhaustive.

All five sections are written by Anectico rather than by the model, so they are always present when
they apply — an answer that quietly dropped a transcript must never read as *"the agent never said
that"*. They are separate sections because they name different things to change:

| Section | What it means | What fixes it |
| --- | --- | --- |
| `## Not examined` | your credential could not read that signal at all | a credential with the signal's permission |
| `## Withheld as sensitive content` | your credential read the signal but may not see that kind of content inside it | a credential with the content permission too |
| `## Withheld by policy` | your project does not allow that content to reach a model | a change to the project's content policy — no credential does it |
| `## Unavailable evidence` | some evidence could not be read or resolved while the answer was assembled | retry after the source is available |
| `## Omitted by evidence limit` | some gathered evidence did not fit in the model input | narrow the question or inspect the named source directly |

Each section states only what was withheld, never that nothing exists. An absent section means
nothing was withheld under that rule, so a complete-looking answer is one you can trust to be
complete.

API and agent clients receive the same information as a structured evidence disclosure containing
closed source and reason values. A present empty omission list means disclosure was evaluated and
nothing was omitted; a missing disclosure means the producer did not populate that contract. Use
the structured form for automation rather than parsing these headings. The field and sections are
generated from the same omission set.

Every project starts with a policy permitting what the product already did, so nothing here changes
until somebody edits it — see
[What may this project's recorded content be used for?](/docs/manage/content-policy).

A content policy belongs to a project, so an investigation that spans your whole organization is
asked project by project rather than once. The organization-wide **LLM spend** question is the one
that does this: each expensive agent run it opens belongs to a single project, and that project's
policy decides whether the run's verbatim messages may be sent. So one answer can carry the
transcripts from a project that permits them and omit those from a project that does not, and the
`## Withheld by policy` section names what was left out.

One part of that answer is still decided differently. The spend **leaderboard** ranks people, and a
person is not confined to one project — so there is no single policy to ask about their profile
label, and the rows are labeled by customer id rather than by name. Everything else about the
leaderboard is unaffected: the spend, tokens, calls and the cost series are not recorded content.
Anchor the investigation on a project, a customer or an agent run when you want the labels too.

## Reopening a saved investigation

An answer is saved, and it outlives the request that produced it: it is returned in full when you
reopen the investigation, listed in the history, and read back into the model when you ask a
follow-up. Both rules above are therefore asked **again, at the moment you read it** — against your
permissions now and your project's content policy now, not the ones in force when it was written.

That matters in one direction in particular. If a saved answer quoted recorded content and your
project has since stopped allowing that content to be shown, the answer stops being shown too. It is
not deleted: widen the policy and it comes back, unchanged. Changing a content policy is a decision
about what may be *disclosed*, and Anectico does not turn it into a decision about what to *keep*.

What you see in place of a withheld answer is the turn itself — the question you asked, when it ran,
and whether it completed — with the answer text and its citations replaced by one sentence saying
why. The citations go with the answer because a citation carries a preview of the evidence behind
it, and for a customer citation the label itself comes from their profile.

There are three of those sentences and they mean different things:

| What it says | Why | What fixes it |
| --- | --- | --- |
| your **role** does not include the recorded content this answer used | you are reading an answer produced by someone with a wider role | a wider role, or re-run the investigation to get an answer built from what you can see |
| your organization's **content settings** no longer allow this content to be shown | the project's content policy was tightened after the answer was written | a change to the content settings — no role restores it |
| the settings that govern showing it **could not be confirmed** | Anectico could not establish which settings apply — most often a temporary problem, or an answer saved before it recorded which project its content came from | retry; if it persists, re-run the investigation |

A saved answer that used no recorded content at all is never affected by any of this — it is shown
to everyone who can open the investigation, exactly as before.

A **follow-up** is refused rather than narrowed for the same reason, with the same three sentences:
a follow-up is answered with the earlier turns in the model's context, so continuing an
investigation you may not be shown would put that content back into a new answer. Start a new
investigation on the same subject instead; it is built from what you can see, under the settings in
force now.

## When no answer is possible

A grounded “not enough evidence” result is preferable to a guess. Check whether the relevant signal
was ingested, sampled, retained, and connected to identity. Use [No data is appearing](/docs/help/no-data) when the evidence itself is absent.

If the AI provider is temporarily unavailable, Detective saves the failed turn and shows the same
safe message when you return to or reload the investigation. Provider responses, credentials, and
other upstream details are never included in that restored message; retry after service recovers.
