# uip pm conformance, uip pm deviations, uip pm query

> Syntax and options for analyzing a Process Mining app — conformance rate, accepted deviations, and ad hoc data queries — with `uip pm conformance`, `uip pm deviations`, and `uip pm query`.

Part of the [`uip pm`](./uip-pm.md) tool. `conformance` and `deviations` are convenience layers over `query`: they resolve the app's internal conformance field IDs for you and answer in plain terms. `query` is the general-purpose escape hatch for anything these two don't cover.

:::note
`conformance` and `deviations` only work on a **model-based** app (`--miner inductive` or `bpmn` at `apps create`, or a BPMN reference model uploaded via `conformance upload-model`). A `directly-follows` app has no reference model and no conformance data — every verb in this group fails with an explicit error naming the miner.
:::

## Synopsis

```text
uip pm conformance rate <app-id> [--process-id <id>] [--stage dev|published]
uip pm conformance activities <app-id> [--process-id <id>] [--stage dev|published]
uip pm conformance transitions <app-id> [--process-id <id>] [--stage dev|published]
uip pm conformance deviations <app-id> [--process-id <id>] [--stage dev|published]
uip pm conformance upload-model <app-id> <bpmn-file> [--process-id <id>]

uip pm deviations list <app-id> [--process-id Process] [--stage dev|published]
uip pm deviations accept <app-id> --type <type> --activities <activities...> [--process-id Process]
uip pm deviations delete <app-id> --type <type> --activities <activities...> [--process-id Process]
uip pm deviations delete-all <app-id> -y [--process-id Process]

uip pm query run <app-id> [--body <file> | --body-json <json> | --group-by <cols> --metric <col:fn[:alias]>...] [--process-graph] [--conformance] [--limit <n>] [--stage dev|published]
uip pm query details <app-id> [--body <file> | --body-json <json>] [--limit <n>] [--stage dev|published]
uip pm query rca <app-id> [--body <file> | --body-json <json>] [--limit <n>] [--stage dev|published]
uip pm query insights <app-id> [--body <file> | --body-json <json>] [--limit <n>] [--stage dev|published]
uip pm query info <app-id> [--stage dev|published]
uip pm query layout <app-id> [--type graph|process-model] [--stage dev|published]
uip pm query percentile <app-id> --field <id> --values <list> [--filters <file> | --filters-json <json>] [--stage dev|published]
```

## uip pm conformance rate

Share of cases that follow the reference model.

### Options

| Long | Value | Description |
|---|---|---|
| `--process-id <id>` | string | Process to report on; only needed for a multi-process app. |
| `--stage <stage>` | `dev` \| `published` | Default `dev`. |

### Example

```bash
uip pm conformance rate 9c46289e
```

### Data shape (--output json)

```json
{ "Code": "PmConformanceRate", "Data": { "ProcessId": "Process", "Miner": "inductive", "ConformanceRate": 0.666667, "ConformingCases": 2, "TotalCases": 3 } }
```

## uip pm conformance activities

Conformance status of each activity, with the cases behind it.

```bash
uip pm conformance activities 9c46289e
```

```json
{ "Code": "PmConformanceActivities", "Data": [{ "Activity": "Approve", "Status": "Conforming", "Cases": 2 }, { "Activity": "Escalate", "Status": "LogOnly", "Cases": 1 }] }
```

`Status` is one of `ModelOnly`, `LogOnly`, `Conforming`, `Accepted`.

## uip pm conformance transitions

Conformance status of each transition between activities.

```bash
uip pm conformance transitions 9c46289e
```

```json
{ "Code": "PmConformanceTransitions", "Data": [{ "FromNodeId": "Start", "ToNodeId": "Approve", "Status": "Conforming", "Cases": 2 }] }
```

## uip pm conformance deviations

Deviations the data actually shows (not to be confused with `uip pm deviations`, which manages *accepted* deviations — this reads what's currently deviating).

```bash
uip pm conformance deviations 9c46289e
```

```json
{ "Code": "PmConformanceDeviations", "Data": [{ "Deviation": "Activity Approve is skipped", "Type": "Skip", "Cases": 1, "AverageThroughputTime": 2700 }] }
```

## uip pm conformance upload-model

Upload a BPMN file as the app's reference model. Dev stage only; takes effect on the next ingestion — the upload alone does not re-measure anything.

### Arguments

| Name | Required | Purpose |
|---|---|---|
| `<app-id>` | yes | Process app ID. |
| `<bpmn-file>` | yes | Local `.bpmn` file, max 6 MB. |

### Options

| Long | Value | Description |
|---|---|---|
| `--process-id <id>` | string | Process the model belongs to; only needed for a multi-process app. |

### Example

```bash
uip pm conformance upload-model 9c46289e ./order-to-cash.bpmn
```

### Data shape (--output json)

```json
{ "Code": "PmConformanceUploadModel", "Data": { "AppId": "9c46289e", "File": "./order-to-cash.bpmn", "Status": "Uploaded", "Messages": [] } }
```

Fails if the file exceeds 6 MB, or if the server validates and rejects the BPMN (`HasError` in the response) — the rejection reasons are surfaced in the failure message, not silently reported as success.

## uip pm deviations

Manage the accepted-deviation list an app is checked against — accepting a deviation makes conformance stop counting it. **Nothing takes effect until transformations re-run**; `list` reports that gap as a per-deviation status.

`--process-id` defaults to `"Process"` on every verb (only matters for a multi-process app).

### uip pm deviations list

| Option | Value | Description |
|---|---|---|
| `--process-id <id>` | string | Default `Process`. |
| `--stage <stage>` | `dev` \| `published` | Default `dev`. |

```json
{ "Code": "PmDeviationsList", "Data": [{ "Type": "activity_missing", "Activities": ["Approve order"], "ParentProcess": [], "Status": "NotApplied" }] }
```

`Status` is `Applied` (the last successful ingestion has it), `NotApplied` (accepted since that ingestion), or `AppliedButDeleted` (deleted since it) — the latter two both mean "re-run transformations to catch up."

### uip pm deviations accept

| Long | Value | Required | Description |
|---|---|---|---|
| `--type <deviation-type>` | string | **yes** | Deviation type, as reported by `conformance deviations`. |
| `--activities <activities...>` | strings, space-separated | **yes** | Activity names the deviation covers. |
| `--process-id <id>` | string | no | Default `Process`. |

```bash
uip pm deviations accept 9c46289e --type activity_missing --activities "Approve order"
```

```json
{ "Code": "PmDeviationsAccept", "Data": { "AppId": "9c46289e", "Type": "activity_missing", "Activities": ["Approve order"], "Status": "Accepted" } }
```

Fails if the exact type/activities/process combination is already accepted. Only reaches top-level deviations — one nested in a subprocess (non-empty `parentProcess`) can't be matched from this command, since `--activities` never sends a `parentProcess`.

### uip pm deviations delete

Same options as `accept`. Stop accepting a deviation — the type, activities, and parent process must match an accepted deviation exactly.

```json
{ "Code": "PmDeviationsDelete", "Data": { "AppId": "9c46289e", "Type": "activity_missing", "Activities": ["Approve order"], "Status": "Deleted" } }
```

### uip pm deviations delete-all

Stop accepting every deviation on the app.

| Long | Value | Description |
|---|---|---|
| `-y, --yes` | flag | Confirm this irreversible operation. Required. |
| `--process-id <id>` | string | Default `Process`. |

```json
{ "Code": "PmDeviationsDeleteAll", "Data": { "AppId": "9c46289e", "Status": "Deleted" } }
```

## uip pm query

General-purpose data queries against a mined app. All body-taking verbs (`run`/`details`/`rca`/`insights`) share `--body <json-file>` / `--body-json <json>` (mutually exclusive), `--stage`, and (except `insights`... actually all four) `--limit` (server clamps to 1..1000).

### uip pm query run

Aggregate (group-by + metrics) query. Supports a sugar syntax on top of the raw body.

| Long | Value | Description |
|---|---|---|
| `--group-by <cols>` | comma-separated | Field columns (names or IDs, from `query info`) to group by. Sugar; mutually exclusive with `--body`/`--body-json`. |
| `--metric <col:fn[:alias]>` | repeatable | Aggregate a field. `fn` is one of `any`, `average`, `count`, `distinct_count`, `forall`, `forany`, `max`, `median`, `min`, `percentage`, `sum` (case-insensitive, `-`/`_` interchangeable). Default alias is `<fn>_<column>`. |
| `--process-graph` | flag | Answer over the process graph (activities/transitions) rather than the plain data model. Sugar-only — a raw body carries `isProcessGraph` itself. |
| `--conformance` | flag | Answer over the model-only side (steps the reference model expected that a case skipped) rather than what the log did do. Sugar-only. |

Other aggregation functions (`COUNT_ROWS`, `EXISTS`, `APPROX_DISTINCT_COUNT`, `PERCENTILE`, `CASE_AVERAGE`) aren't available through `--metric` — author them with `--body`/`--body-json` (use `query percentile` for percentiles specifically).

### Examples

```bash
uip pm query run 9c46289e --group-by Open_year --metric Event_count:average
```

```bash
uip pm query run 9c46289e --body-json '{"groupBy":["F__Cases__Priority__..."],"aggregates":[{"id":"n","argument":"Case_ID","aggregation":"COUNT"}]}'
```

```bash
uip pm query run 9c46289e --metric Case_conforming:percentage
```

```bash
# Skipped steps: activities the reference model expected that a case didn't take
uip pm query run 9c46289e --group-by Node_id,Node_label --metric Case_ID:distinct_count --process-graph --conformance
```

### Data shape (--output json)

```json
{ "Code": "PmQueryRun", "Data": [{ "Open_year": 2014, "average_Event_count": 9.16 }] }
```

With the sugar syntax, the engine's columnar response is reshaped into row objects keyed by human column names/aliases; a raw `--body`/`--body-json` call returns the engine's response as-is.

### uip pm query details

Raw table rows.

```json
{ "Code": "PmQueryDetails", "Data": {} }
```

### uip pm query rca

Root-cause analysis. Body needs a non-empty `selectedSet`.

```bash
uip pm query rca 9c46289e --body-json '{"argument":"Case_ID","exploreAttributes":["Case_type"],"selectedSet":[[{"kind":"values","dimension":"Case_status","type":"string","values":["Open"],"invert":false,"displayType":"list"}]]}'
```

```json
{ "Code": "PmQueryRca", "Data": { "Data": {}, "Warnings": null } }
```

### uip pm query insights

Process insights. Body needs `processId` and 1-10 `metrics`.

```json
{ "Code": "PmQueryInsights", "Data": {} }
```

### uip pm query info

Discover the fields, metrics, and processes available for query bodies.

```bash
uip pm query info 9c46289e
```

```json
{ "Code": "PmQueryInfo", "Data": { "fields": [], "processes": [] } }
```

### uip pm query layout

Get the persisted global graph layout of a process app.

| Long | Value | Default | Description |
|---|---|---|---|
| `--type <type>` | `graph` \| `process-model` | `graph` | Which layout to read. |

```json
{ "Code": "PmQueryLayout", "Data": {} }
```

### uip pm query percentile

Compute percentiles of a numeric field.

| Long | Value | Required | Description |
|---|---|---|---|
| `--field <field-id>` | string | **yes** | Field ID (`query info`). |
| `--values <list>` | comma-separated, 0..1 | **yes** | Percentile points, e.g. `0.5,0.9,0.95`. |
| `--filters <json-file>` / `--filters-json <json>` | JSON | no | Filter spec (array of AND-ed filter groups). Mutually exclusive. |

```bash
uip pm query percentile 9c46289e --field PF__throughput_time --values 0.5,0.9,0.95
```

```json
{ "Code": "PmQueryPercentile", "Data": { "values": [3600, 86400, 172800] } }
```

## Related

- [`uip pm`](./uip-pm.md) — overview and `apps` CRUD.
- [`apps model`](./uip-pm-apps-model.md) — field/metric definitions these queries reference.
- [`ingestions` & `transformations`](./uip-pm-ingestion.md) — a query needs a completed ingestion on the stage it targets.

## See also

- [Global options](./global-options.md)
- [Exit codes](./exit-codes.md)
