> ## Documentation Index
> Fetch the complete documentation index at: https://docs.firedog.finance/llms.txt
> Use this file to discover all available pages before exploring further.

# Sensitivity profiles

> Choose what the in-VPC collector is allowed to emit as metadata — strict, standard, or open — without ever letting prompt or response content leave your network.

A sensitivity profile controls **what the collector emits to Firedog cloud**. It is the single dial that governs how much of each call's *attribution metadata* — workflow labels, team labels, user identity, category, quality signal — is sent to the control plane, and in what form (emitted as-is, hashed, or dropped).

It does **not** govern your prompts, your RAG chunks, or your model responses. Those live in the full `CallRecord` written to the Postgres inside your VPC and are never part of what the collector sends.

<Warning>
  Under **every** profile — strict, standard, and open — prompt and response content never leaves your VPC. Sensitivity profiles only shape the **metadata tags**. See [Security](/security) and [How it works](/how-it-works) for the split-plane model.
</Warning>

## The two records

Every call produces two records. The profile only ever touches the second one.

<CardGroup cols={2}>
  <Card title="CallRecord (full)" icon="database">
    Prompt messages, RAG chunks, and the response. Written to **Postgres inside your VPC**. Never emitted to the cloud, under any profile. A drill-down fetches it from the collector, within your network, keyed by `callId`.
  </Card>

  <Card title="CallMetadata" icon="tags">
    The costed, attributed metadata line emitted to Firedog cloud. `callId`, `cost`, token counts, `latencyMs`, `model`, plus the attribution tags. **This is the only thing a profile shapes.**
  </Card>
</CardGroup>

The `callId` (a ULID minted client-side) is the correlation key between the two. It is always emitted — it carries no business meaning on its own and is what lets a dashboard drill-down go back to the collector for the full record. See [Attribution](/attribution) for where the tags come from.

## The three profiles

<CardGroup cols={3}>
  <Card title="strict" icon="lock">
    Maximal redaction. Labels are hashed, user identity is always hashed, category is dropped when it could identify. For regulated or PII-heavy desks.
  </Card>

  <Card title="standard" icon="scale-balanced">
    Balanced, and the default. Raw workflow and team labels, salted user hash, quality signal retained. Right for most desks.
  </Card>

  <Card title="open" icon="unlock">
    Richest tags. Raw labels and category, salted user hash. For internal tooling whose labels aren't sensitive.
  </Card>
</CardGroup>

## What each profile emits

Columns are the profiles; each cell describes what happens to that field in the **emitted metadata**. "Hashed" means a stable, non-reversible token (salted for user identity) so you can still group and count without exposing the underlying label. "Dropped" means the field is omitted from the metadata entirely.

<Note>
  These are the **configurable defaults** for each profile, not hard guarantees. Your collector configuration is the source of truth; treat the table as the shape each profile ships with.
</Note>

| Metadata field                             | strict                                    | standard             | open                 |
| ------------------------------------------ | ----------------------------------------- | -------------------- | -------------------- |
| **Prompt / response content**              | Never emitted                             | Never emitted        | Never emitted        |
| **Workflow & team tags**                   | Hashed (e.g. `Project-Titan` → `wf_7c2a`) | Emitted (raw labels) | Emitted (raw labels) |
| **User identity** (`userHash`)             | Hashed (salted)                           | Hashed (salted)      | Hashed (salted)      |
| **Category**                               | Dropped if it could identify              | Emitted              | Emitted              |
| **Quality signal** (`qaOverall`)           | Dropped                                   | Emitted              | Emitted              |
| **Shadow saving** (`shadowSaving`)         | Emitted                                   | Emitted              | Emitted              |
| **Cost, tokens, latency, model, `callId`** | Emitted                                   | Emitted              | Emitted              |

A few notes on the mechanics:

* **User identity is never raw.** Across all three profiles the collector emits a `userHash` — a salted, non-reversible hash — never the raw `x-firedog-user` value. strict and standard differ on the *labels*, not on whether the user is protected.
* **Hashing preserves grouping.** A hashed tag like `wf_7c2a` is stable, so the dashboard can still show cost per workflow and per user under strict — you get the accounting slice without the human-readable name.
* **The costed line always survives.** `cost`, `promptTokens`, `completionTokens`, `latencyMs`, `model`, and `callId` are emitted under every profile — otherwise the reconciled bill on [Home](/how-it-works) and the slices on [Cost allocation](/how-it-works) couldn't be built. The profile trims *identifying tags*, not the money.
* **`shadowSaving` is a number, never content.** [Shadow testing](/quality-shadow-testing) emits only the measured saving, so it rides along under strict too. `qaOverall` is dropped under strict because a per-call quality score tied to a hashed-but-narrow workflow can be more revealing than a dollar figure.

## Recommended profile per data class

Set the profile to the sensitivity of the **labels** a desk attaches to its calls — not the sensitivity of the prompts, which stay in your VPC regardless.

<AccordionGroup>
  <Accordion title="strict — regulated or PII-heavy desks" icon="building-columns">
    Deal teams, client-facing advisory, anything under information-barrier or regulated-data controls where a workflow name (`Project-Titan`) or category could itself signal a live mandate. You still get cost per workflow, per user, and per model — just under hashed labels. Pair with the guidance in [Security](/security).
  </Accordion>

  <Accordion title="standard — the default for most desks" icon="scale-balanced">
    Research, macro, quant, and other desks where team and workflow names are internal but not sensitive. Raw labels make [Cost allocation](/how-it-works) and [Answer quality](/quality-shadow-testing) directly readable while user identity stays hashed. Start here unless a data class argues otherwise.
  </Accordion>

  <Accordion title="open — internal tooling" icon="screwdriver-wrench">
    Platform, developer tooling, and back-office automation whose labels carry no confidentiality. Keeps category and quality signal for the richest breakdowns. User identity is still salted-hashed — open widens tag richness, not user exposure.
  </Accordion>
</AccordionGroup>

<Tip>
  You don't have to pick one profile for the whole firm. Run one collector per data class (or per desk) and set the profile on each, so a regulated desk emits `strict` while your platform team emits `open` — same dashboard, different emission rules.
</Tip>

## Configuring the profile

The profile is set on the collector — the data-plane component inside your VPC — so the decision about what may leave your network is made and enforced on your side, before anything is emitted.

<Note>
  Configuration surface below is illustrative. *\[Placeholder — confirm the exact collector configuration keys and deploy artifact with the Firedog team.]*
</Note>

<CodeGroup>
  ```yaml collector.yaml theme={null}
  # In-VPC collector configuration
  collector:
    id: "collector-macro-01"
    tenantId: "acme-cap"

    # Where the full CallRecord is persisted — inside your VPC, never emitted.
    storage:
      postgresUrl: "postgres://firedog@db.internal:5432/firedog"

    # The single dial governing emitted metadata.
    sensitivityProfile: "standard"   # "strict" | "standard" | "open"

    # Salt for the user hash. Held only in your VPC; rotate per your policy.
    userHashSalt: "${FIREDOG_USER_HASH_SALT}"
  ```

  ```bash Environment theme={null}
  # Same setting via environment, for containerised deploys.
  FIREDOG_SENSITIVITY_PROFILE=strict
  FIREDOG_USER_HASH_SALT=...        # never leaves your VPC
  ```
</CodeGroup>

Because the profile lives on the collector and the collector runs in your VPC, the emission rules are applied **before** any metadata is sent — the control plane only ever receives what your profile already allowed through.

## What a profile does not change

<Check>Prompt, response, and RAG content — always stays in your VPC, every profile.</Check>
<Check>The reconciled, to-the-cent bill — cost and token fields are always emitted.</Check>
<Check>Drill-down to the full call — always served from the collector inside your VPC, keyed by `callId`.</Check>

<Info>
  Next: see [Security](/security) for the split-plane threat model, and [Attribution](/attribution) for where the tags come from.
</Info>
