> For the complete documentation index, see [llms.txt](https://help.sharkdom.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.sharkdom.com/feature-suite/dweep-scouting-mcp/reading-the-telemetry.md).

# Reading the telemetry

What the service records about every call, every search and every verdict, how it gets there, what it can tell you and the three ways it will mislead you if rea

### What exists

Four tables, live and collecting. Everything below is what the deployed service is doing right now, not a plan.

<figure><img src="https://3954960519-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FadTM8GarVeiEakkopgTw%2Fuploads%2FmMhU0VjurucdE7uvJcdq%2Fimage.png?alt=media&amp;token=f14ee140-eb9d-4b6c-bff4-b42f27d290ce" alt=""><figcaption></figcaption></figure>

*They sit alongside `dweep_audit_log`, which is deliberately separate and unchanged in character: audit answers who did what to whom and is read when somebody has to account for something. Burying a million latency rows in it would make that read useless.*

{% hint style="info" %}
**Everything is scoped by organisation**

All four tables carry `org_id`; `tool_call`, `discovery_run` and `feedback` also carry `u_id`, and `org_day` is keyed on `(org_id, day, tool)`. Every question below can be asked per organisation, per person, or across the whole service.
{% endhint %}

### The workflow

From an assistant calling a tool to a row you can query. Nothing here is opt-in per tool.

* A tool is calledThe identity middleware resolves who is calling, starts a clock, and captures the *shape* of the arguments.
* The gate runsIf the caller is refused, that is recorded as `refused` with the gate's own reason not as an error, and not as silence.
* The tool runsOn return, the payload is classified: `action_required` means refused, `error` means error, anything else is `ok`. Result counts are pulled from the payload where present.
* One row is writtenInto `dweep_tool_call`, in its own transaction, swallowing any failure. Measuring must never break what it measures.
* A search returns companiesA `dweep_discovery_run` row captures the brief, how it was interpreted, how many companies and contacts came back, and whether the run completed.
* The person is askedOnce, after results and again after a draft. Server instructions tell the assistant to ask plainly and to accept silence.
* A verdict is recorded`submit_feedback` writes to `dweep_feedback`, pointing at the run.
* NightlyDays are rolled into `dweep_org_day`, then raw call rows past retention are dropped rollup first, always.

{% hint style="info" %}
**One hook, not twenty-one decorators**

Instrumentation lives in `IdentityMiddleware.__call__`, which already wraps every `tools/call` to resolve the caller and gate the tool. A tool written tomorrow is measured by existing rather than by somebody remembering to annotate it, the same reasoning the account-tool gate uses, and for the same reason: a hand-maintained list drifts, and the drift is silent.
{% endhint %}

### Tool calls

`dweep_tool_call` — the spine. Everything else is a smaller table that points into the same conversation.

<figure><img src="https://3954960519-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FadTM8GarVeiEakkopgTw%2Fuploads%2FBDWBpMeL3szHA0aPcidg%2Fimage.png?alt=media&amp;token=5f557a8d-2606-4c35-9f6e-5a1d4c544cac" alt=""><figcaption></figcaption></figure>

**arg\_shape, as actually written**

live row · scout\_partners

```
{"limit": "number", "prompt_len": 74, "fetch_contacts": false}
```

The brief was 74 characters. What it *said* is not here, that lives on the run row, where it has a reason to exist and a retention story. This is the highest-volume table and the least access-controlled read path, so it holds shapes.

{% hint style="info" %}
**Refused is not error**

A refusal means the gate worked: no binding, no identity, seat limit, wrong account. That is an **onboarding** signal, and it should rise when you add customers and fall as they finish setting up. An error is a **reliability** signal and should trend to zero. Counting them together produces a number that means nothing and can only be argued about.
{% endhint %}

### Discovery runs

`dweep_discovery_run` — the unit a person actually forms an opinion about.

live row

```
run_id      bfda92f3-4fa4-4561-931d-de92458183d8
brief       cloud consulting and systems integrator companies
            that resell CRM software
filters     {"where": "United States",
             "partnership_type": "Resellers & Channel Partners"}
rounds      1
companies   3        contacts   0
sources     {"requested": ["aws"], "contacts_fetched": false,
             "attribution": "not_tracked"}
completed   True
```

`brief` and `resolved_filters` are the pair that matter. The brief is what was asked; the filters are what the service decided that meant. **The most common cause of a bad result is a wrong reading of the brief**, and with only one of the two there is no telling a bad search from a bad interpretation.

`clarification_rounds` rising across a period means briefs are being understood less well. `completed` is false when a run returned nothing, a dissatisfaction signal nobody had to type.

{% hint style="info" %}
**Sources\_used says what it knows**

It records the marketplaces that were *requested*, and carries `attribution: "not_tracked"` to say so. The useful question which source actually contributed, so a source going quiet becomes visible cannot be answered: nothing in the pipeline tags a company with its origin. Answering it means tagging during discovery, which is a pipeline change, not a telemetry one.
{% endhint %}

### Feedback

`dweep_feedback` one row per stated verdict, kept whichever way it went.

<figure><img src="https://3954960519-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FadTM8GarVeiEakkopgTw%2Fuploads%2FinrfCTq5xaYQI2c1Q0no%2Fimage.png?alt=media&amp;token=f9fd7c44-f3c1-46ba-b332-bc9826a0e085" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
**Why two values and not five stars**

A scale invites a shrug. Most responses land in the middle, and a middle is not actionable nobody can tell what to change from a three. A binary forces a small decision and produces a number that moves when something real changes.
{% endhint %}

### Connect attempts

Not a table of its own, the connect funnel lives in `dweep_audit_log`, because each of these is something somebody might later have to account for.

Connecting a LinkedIn account is the single biggest point of friction in onboarding: it needs a human, a browser and a sign-in, and it is where people stall. The stages below are recorded per person, per organisation, and can be counted.

<figure><img src="https://3954960519-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FadTM8GarVeiEakkopgTw%2Fuploads%2F32HBtKpvZYtnroM5a1c2%2Fimage.png?alt=media&amp;token=e9a56915-2f74-4295-aab5-fa72f34ef07d" alt=""><figcaption></figcaption></figure>

**What a link\_issued row carries**

```
{"stage": "link_issued", "attempt": 3, "reconnect": true,
 "conversation": "conn-A", "binding_id": "776eff2b-…"}
```
