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

# PCE Workflow: State Machine Phases and Execution Modes

> Walk through the PCE state machine phases, execution mode selection logic, and standalone helpers available for custom integrations.

The PCE agent runs a 5-phase state machine for every change request, followed by packet generation and human review. Each phase has a clear responsibility and produces output consumed by the next. You can run the full pipeline through `pce.processChangeRequest()`, or call individual phase helpers directly when you need more control over a custom workflow.

## State Machine Phases

**1. Collect Evidence**

`collectPceEvidenceSources()` merges any explicit sources you provide with results fetched through the configured `SourceRetriever`. The merged list becomes `state.evidenceSources` and is used for grounding in every subsequent phase.

```typescript theme={"system"}
import { collectPceEvidenceSources } from "@claritylabs/cl-sdk";

const evidence = await collectPceEvidenceSources(
  { requestText, evidenceSources: explicitSources },
  { sourceRetriever, retrievalLimit: 8 },
);
```

**2. Normalize Changes**

The request text is parsed into `PolicyChangeItem[]`. The SDK first attempts model-based structured extraction; if the model returns low-confidence output, a heuristic fallback parser runs to ensure at least a partial item list is available for downstream phases.

Each item includes:

* `fieldPath` — dot-separated path to the target policy field
* `proposedValue` — the value being added or modified
* `action` — `add` | `modify` | `remove`
* `citations` — source references that support the change
* `confidence` — extraction confidence score

**3. Ask Missing Info**

After normalization, the agent checks each `PolicyChangeItem` against its field requirements. Any required field that cannot be resolved from evidence or the request text produces a `PceMissingInfoQuestion`. Each question is tied to an `itemId` and `fieldPath` so your UI can target the prompt precisely.

Check `state.missingInfoQuestions.length` before advancing to avoid generating an incomplete submission packet.

**4. Validate Items**

`validatePceItems()` checks normalized items against the collected evidence. It produces `CaseValidationIssue[]` with severity levels:

* **`blocking`** — must be resolved or intentionally overridden before the case is considered submission-ready
* **`warning`** — should be reviewed but does not block packet generation
* **`info`** — informational notes for the reviewer

Validation checks include quote accuracy (is the cited text actually present in the source?), field path recognisability, and cross-item consistency.

**5. Select Execution Mode**

`selectPceExecutionMode()` evaluates the normalised items, evidence confidence scores, and carrier constraints to pick the appropriate automation posture. When you pass `executionMode: "auto"` to `createPceAgent()`, this phase runs automatically.

| Mode | Selection criteria |
| - | - |
| `deterministic_tree` | All items are high-confidence, no missing info, carrier rules are deterministic |
| `market_eval` | Ambiguous items, low evidence confidence, or market-specific carrier constraints |
| `hybrid` | Mixed confidence — deterministic scaffolding with model interpretation for edge cases |

**6. Build Submission Packet**

The agent assembles a `PceSubmissionPacket` containing carrier artifacts, validation issues, missing-info questions, and a timestamp. See the [Submission Packet guide](https://claritylabs.inc/docs/cl-sdk/pce/submission-packet.md) for the full packet structure and quality gate API.

**7. Human Review**

The generated packet is surfaced for review by a licensed user. The SDK does not submit to carriers — the packet is a draft until a reviewer confirms that evidence, missing-info status, and the validation report meet their standards.

***

## Processing a Reply to Missing-Info Questions

When `state.missingInfoQuestions` is non-empty, present the questions to the user and pass their reply back to the agent. The agent re-runs normalization and validation against the enriched information.

```typescript theme={"system"}
const reply = await pce.processReply({
  state,
  replyText: "The effective date should be June 1, 2026.",
});

// reply.state now has the updated items, reduced missingInfoQuestions,
// and a fresh validation report.
if (reply.state.missingInfoQuestions.length === 0) {
  const packet = pce.generateSubmissionPacket({ state: reply.state });
}
```

> [!TIP]
>
> If your application has a structured form rather than free-text replies, you can construct `replyText` from the form values before passing it to `processReply()`. The agent treats it as plain text input.

***

## Execution Modes in Detail

**deterministic\_tree**

**Use when:** All change items are high-confidence, no missing info remains, and carrier validation rules are deterministic (e.g. a well-described vehicle addition with VIN, year, make, model, and effective date all present).

This mode runs through a constrained rule tree without model-assisted interpretation, keeping latency and token cost low.

**market\_eval**

**Use when:** One or more items are ambiguous, evidence confidence is low, or the carrier has market-specific constraints that require heavier interpretation.

This mode adds model-assisted reasoning steps and flags more items for reviewer attention. Expect higher token usage and more detailed validation output.

**hybrid**

**Use when:** Most items are clear but a few edge cases need model interpretation — for example, a multi-item request where the vehicle addition is deterministic but an accompanying coverage modification is ambiguous.

Deterministic scaffolding runs for high-confidence items; model-assisted interpretation runs only for items that need it.

**auto**

**Use when:** You want the SDK to decide. `selectPceExecutionMode()` evaluates the case and picks `deterministic_tree`, `market_eval`, or `hybrid`. Recommended for production use unless you have a strong reason to force a specific mode.

***

## Standalone Helpers

You can import and call PCE phase helpers directly for custom workflows, testing, or when you need fine-grained control over individual phases.

```typescript theme={"system"}
import {
  collectPceEvidenceSources,
  validatePceItems,
  selectPceExecutionMode,
  stablePolicyChangeItemId,
} from "@claritylabs/cl-sdk";
```

**collectPceEvidenceSources(input, options)** `Promise\<CaseEvidenceSource[]\>`

Merges explicit evidence sources with retriever results for a given `requestText`. Returns deduplicated `CaseEvidenceSource[]`.

**validatePceItems(items, sources)** `CaseValidationIssue[]`

Validates normalized `PolicyChangeItem[]` against `CaseEvidenceSource[]`. Returns issues grouped by `itemId` and `fieldPath`.

**selectPceExecutionMode(state)** `"deterministic_tree" | "market_eval" | "hybrid"`

Evaluates a `PceCaseState` and returns the most appropriate execution mode.

**stablePolicyChangeItemId(inputs)** `string`

Generates a deterministic, hash-based ID for a change item from its field path and proposed value. Safe for deduplication and retry — the same logical change always produces the same ID.

***

## Error Handling

> [!WARNING]
>
> If `processChangeRequest()` resolves with `state.validationIssues` containing blocking issues and `state.missingInfoQuestions` is non-empty, do not proceed to `generateSubmissionPacket()`. The packet will be generated but the embedded quality report will reflect a `"failed"` gate status, and the artifacts will be marked as incomplete.

Always check both conditions before advancing:

```typescript theme={"system"}
const { state } = await pce.processChangeRequest({ requestText, caseId });

const hasBlockingIssues = state.validationIssues.some(
  (issue) => issue.severity === "blocking",
);

if (state.missingInfoQuestions.length > 0 || hasBlockingIssues) {
  // Resolve issues before generating the packet.
  return;
}

const packet = pce.generateSubmissionPacket({ state });
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.