@lexq/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,264 @@
1
+ # LexQ CLI — Policy Rules
2
+
3
+ > **Prerequisite:** Read `lexq-shared/SKILL.md` first.
4
+
5
+ ## Overview
6
+
7
+ A **Policy Rule** is a condition → actions pair within a version. Rules are evaluated in priority order (0 = highest). When a rule's condition matches the input facts, its actions fire.
8
+
9
+ ## Rule Structure
10
+
11
+ ```json
12
+ {
13
+ "name": "VIP 10% Discount",
14
+ "priority": 0,
15
+ "condition": { ... },
16
+ "actions": [ ... ],
17
+ "mutexGroup": null,
18
+ "mutexMode": "NONE",
19
+ "mutexStrategy": "FIRST_MATCH",
20
+ "mutexLimit": null,
21
+ "isEnabled": true
22
+ }
23
+ ```
24
+
25
+ ## Condition Syntax
26
+
27
+ Conditions use a tree structure with two node types: `SINGLE` and `GROUP`.
28
+
29
+ ### SINGLE Condition
30
+
31
+ ```json
32
+ {
33
+ "type": "SINGLE",
34
+ "field": "payment_amount",
35
+ "operator": "GREATER_THAN_OR_EQUAL",
36
+ "value": 100000,
37
+ "valueType": "NUMBER"
38
+ }
39
+ ```
40
+
41
+ ### GROUP Condition (logical combinator)
42
+
43
+ ```json
44
+ {
45
+ "type": "GROUP",
46
+ "operator": "AND",
47
+ "children": [
48
+ {
49
+ "type": "SINGLE",
50
+ "field": "customer_tier",
51
+ "operator": "EQUALS",
52
+ "value": "VIP",
53
+ "valueType": "STRING"
54
+ },
55
+ {
56
+ "type": "SINGLE",
57
+ "field": "payment_amount",
58
+ "operator": "GREATER_THAN",
59
+ "value": 50000,
60
+ "valueType": "NUMBER"
61
+ }
62
+ ]
63
+ }
64
+ ```
65
+
66
+ ### Operators
67
+
68
+ | Operator | Types | Description |
69
+ |---|---|---|
70
+ | `EQUALS` | all | Exact match |
71
+ | `NOT_EQUALS` | all | Negation |
72
+ | `GREATER_THAN` | NUMBER | `>` |
73
+ | `GREATER_THAN_OR_EQUAL` | NUMBER | `>=` |
74
+ | `LESS_THAN` | NUMBER | `<` |
75
+ | `LESS_THAN_OR_EQUAL` | NUMBER | `<=` |
76
+ | `CONTAINS` | STRING | Substring match |
77
+ | `IN` | STRING, NUMBER | Value is in the provided list |
78
+ | `NOT_IN` | STRING, NUMBER | Value is not in the provided list |
79
+
80
+ ### Value Types
81
+
82
+ | Type | JSON Value | Example |
83
+ |---|---|---|
84
+ | `STRING` | `"string"` | `"VIP"` |
85
+ | `NUMBER` | `number` | `100000` |
86
+ | `BOOLEAN` | `true/false` | `true` |
87
+ | `LIST_STRING` | `["a","b"]` | `["KR","US"]` |
88
+ | `LIST_NUMBER` | `[1,2]` | `[10000, 20000]` |
89
+
90
+ ### Nested Conditions Example
91
+
92
+ `(customer_tier = "VIP" AND payment_amount >= 100000) OR region IN ["KR", "JP"]`:
93
+
94
+ ```json
95
+ {
96
+ "type": "GROUP",
97
+ "operator": "OR",
98
+ "children": [
99
+ {
100
+ "type": "GROUP",
101
+ "operator": "AND",
102
+ "children": [
103
+ { "type": "SINGLE", "field": "customer_tier", "operator": "EQUALS", "value": "VIP", "valueType": "STRING" },
104
+ { "type": "SINGLE", "field": "payment_amount", "operator": "GREATER_THAN_OR_EQUAL", "value": 100000, "valueType": "NUMBER" }
105
+ ]
106
+ },
107
+ {
108
+ "type": "SINGLE", "field": "region", "operator": "IN", "value": ["KR", "JP"], "valueType": "LIST_STRING"
109
+ }
110
+ ]
111
+ }
112
+ ```
113
+
114
+ ## Action Types
115
+
116
+ Each rule can have multiple actions. Actions fire sequentially.
117
+
118
+ | Type | Description | Key Parameters |
119
+ |---|---|---|
120
+ | `DISCOUNT` | Apply a discount | `method` (PERCENTAGE/FIXED), `rate`, `referenceFactKey` |
121
+ | `POINT` | Award points | `amount`, `pointType` |
122
+ | `COUPON_ISSUE` | Issue a coupon | `couponId`, `expiryDays` |
123
+ | `BLOCK` | Block the transaction | `reason`, `code` |
124
+ | `NOTIFICATION` | Send notification | `channel`, `template` |
125
+ | `WEBHOOK` | Call external URL | `url`, `method`, `headers`, `body` |
126
+ | `SET_FACT` | Set an output variable | `key`, `value` |
127
+ | `ADD_TAG` | Add a tag to the result | `tag` |
128
+
129
+ ### Action Example: 10% Percentage Discount
130
+
131
+ ```json
132
+ {
133
+ "type": "DISCOUNT",
134
+ "parameters": {
135
+ "method": "PERCENTAGE",
136
+ "rate": 10,
137
+ "referenceFactKey": "payment_amount"
138
+ }
139
+ }
140
+ ```
141
+
142
+ ### Action Example: Block Transaction
143
+
144
+ ```json
145
+ {
146
+ "type": "BLOCK",
147
+ "parameters": {
148
+ "reason": "Suspected fraud",
149
+ "code": "FRAUD_DETECTED"
150
+ }
151
+ }
152
+ ```
153
+
154
+ ## CRUD Commands
155
+
156
+ ### List Rules
157
+
158
+ ```bash
159
+ lexq rules list --group-id <gid> --version-id <vid> --page 0 --size 20
160
+ ```
161
+
162
+ ### Get Rule Detail
163
+
164
+ ```bash
165
+ lexq rules get --group-id <gid> --version-id <vid> --id <ruleId>
166
+ ```
167
+
168
+ ### Create Rule
169
+
170
+ **Important:** Always run `lexq facts list` first to confirm available fact keys and types.
171
+
172
+ ```bash
173
+ lexq rules create --group-id <gid> --version-id <vid> --json '{
174
+ "name": "VIP 10% Discount",
175
+ "priority": 0,
176
+ "condition": {
177
+ "type": "GROUP",
178
+ "operator": "AND",
179
+ "children": [
180
+ { "type": "SINGLE", "field": "customer_tier", "operator": "EQUALS", "value": "VIP", "valueType": "STRING" },
181
+ { "type": "SINGLE", "field": "payment_amount", "operator": "GREATER_THAN_OR_EQUAL", "value": 100000, "valueType": "NUMBER" }
182
+ ]
183
+ },
184
+ "actions": [
185
+ {
186
+ "type": "DISCOUNT",
187
+ "parameters": { "method": "PERCENTAGE", "rate": 10, "referenceFactKey": "payment_amount" }
188
+ }
189
+ ],
190
+ "isEnabled": true
191
+ }'
192
+ ```
193
+
194
+ ### Update Rule
195
+
196
+ ```bash
197
+ lexq rules update --group-id <gid> --version-id <vid> --id <ruleId> --json '{
198
+ "name": "VIP 15% Discount",
199
+ "actions": [
200
+ {
201
+ "type": "DISCOUNT",
202
+ "parameters": { "method": "PERCENTAGE", "rate": 15, "referenceFactKey": "payment_amount" }
203
+ }
204
+ ]
205
+ }'
206
+ ```
207
+
208
+ ### Delete Rule
209
+
210
+ ```bash
211
+ lexq rules delete --group-id <gid> --version-id <vid> --id <ruleId>
212
+ lexq rules delete --group-id <gid> --version-id <vid> --id <ruleId> --force
213
+ ```
214
+
215
+ ### Reorder Rules
216
+
217
+ Pass rule IDs in desired priority order (index 0 = highest priority):
218
+
219
+ ```bash
220
+ lexq rules reorder --group-id <gid> --version-id <vid> \
221
+ --rule-ids "ruleId_A,ruleId_B,ruleId_C"
222
+ ```
223
+
224
+ ### Toggle Rule
225
+
226
+ Enable or disable a rule without deleting it:
227
+
228
+ ```bash
229
+ lexq rules toggle --group-id <gid> --version-id <vid> --id <ruleId> --enabled true
230
+ lexq rules toggle --group-id <gid> --version-id <vid> --id <ruleId> --enabled false
231
+ ```
232
+
233
+ ## Mutex (Rule-Level Conflict Resolution)
234
+
235
+ Within a single version, rules can belong to a `mutexGroup` to limit how many fire.
236
+
237
+ | mutexMode | Behavior |
238
+ |---|---|
239
+ | `NONE` | All matching rules fire (default) |
240
+ | `EXCLUSIVE` | Only one rule per mutex group fires |
241
+ | `MAX_N` | Up to `mutexLimit` rules per mutex group fire |
242
+
243
+ ```bash
244
+ lexq rules create --group-id <gid> --version-id <vid> --json '{
245
+ "name": "Discount A",
246
+ "priority": 0,
247
+ "mutexGroup": "discounts",
248
+ "mutexMode": "EXCLUSIVE",
249
+ "mutexStrategy": "HIGHEST_PRIORITY",
250
+ "condition": { ... },
251
+ "actions": [ ... ]
252
+ }'
253
+ ```
254
+
255
+ **Constraint:** All rules in the same `mutexGroup` must use identical `mutexMode` and `mutexStrategy`.
256
+
257
+ ## Pre-Create Checklist
258
+
259
+ Before creating rules, always:
260
+
261
+ 1. **Check available facts:** `lexq facts list`
262
+ 2. **Confirm the version is DRAFT:** `lexq versions get --group-id <gid> --id <vid>` → status must be `DRAFT`
263
+ 3. **Use exact fact keys** from the fact definitions (snake_case, case-sensitive)
264
+ 4. **Match value types** — a fact defined as `NUMBER` must receive numeric values, not strings
@@ -0,0 +1,139 @@
1
+ # LexQ CLI — Shared Context
2
+
3
+ > **Read this skill first.** All other LexQ skills assume you have read this document.
4
+
5
+ ## What is LexQ?
6
+
7
+ LexQ is a **policy execution engine**. Customers define business rules (conditions → actions), deploy them to production, and execute them via API — all without touching application code. Core differentiators are **pre-deploy simulation** and **A/B testing** for rule versions.
8
+
9
+ ## Authentication
10
+
11
+ ```bash
12
+ # Store your API key (persisted at ~/.lexq/config.json)
13
+ lexq auth login
14
+ # Enter your API Key: lxk_xxxxxxxxxxxxx
15
+
16
+ # Verify authentication
17
+ lexq auth whoami
18
+ ```
19
+
20
+ The API key is passed as `X-API-KEY` header on every request. You can also override per-command:
21
+
22
+ ```bash
23
+ lexq groups list --api-key lxk_override_key
24
+ ```
25
+
26
+ **Base URL:** `https://api.lexq.io/api/v1/partners` (default). Override with `--base-url`.
27
+
28
+ ## Core Concepts
29
+
30
+ | Concept | Description | Analogy |
31
+ |---|---|---|
32
+ | **Policy Group** | A container for rule versions. Has a lifecycle status (ACTIVE / DISABLED / ARCHIVED). | Git repository |
33
+ | **Policy Version** | A snapshot of rules within a group. Follows DRAFT → ACTIVE → ARCHIVED lifecycle. | Git branch / commit |
34
+ | **Policy Rule** | A condition + actions pair within a version. Evaluated in priority order. | if-then statement |
35
+ | **Fact Definition** | Input schema — declares available variables and their types (STRING, NUMBER, BOOLEAN, LIST_STRING, LIST_NUMBER). | Function parameter |
36
+ | **Deployment** | Promotes a PUBLISHED version to live traffic. Supports rollback. | Production release |
37
+ | **Dry Run** | Tests a single input against a DRAFT or ACTIVE version without side effects. | Unit test |
38
+ | **Simulation** | Batch-tests a version against historical execution data. Compares with a baseline. | Integration test suite |
39
+
40
+ ## Standard Workflow
41
+
42
+ This is the typical lifecycle. **Always follow this order:**
43
+
44
+ ```
45
+ 1. lexq groups create → Create a policy group
46
+ 2. lexq versions create → Create a DRAFT version inside it
47
+ 3. lexq facts create → Register input variables (if not already defined)
48
+ 4. lexq rules create → Add rules with conditions + actions
49
+ 5. lexq analytics dry-run → Test with sample facts (validate before publish)
50
+ 6. lexq deploy publish → DRAFT → ACTIVE (locks the version)
51
+ 7. lexq deploy live → Deploy ACTIVE version to production
52
+ 8. lexq analytics simulation → Run batch comparison against baseline (optional)
53
+ ```
54
+
55
+ ### Critical Ordering Constraints
56
+
57
+ - **Cannot create rules without a DRAFT version.** Create the version first.
58
+ - **Cannot publish without at least one rule.** Add rules before publishing.
59
+ - **Cannot modify a published version.** Clone it to create a new DRAFT if changes are needed.
60
+ - **Cannot deploy a DRAFT version.** Must publish first (DRAFT → ACTIVE).
61
+ - **Always run `lexq analytics dry-run` before publishing.** This is your safety net.
62
+
63
+ ## Global Options
64
+
65
+ Every command accepts these flags:
66
+
67
+ | Flag | Description | Default |
68
+ |---|---|---|
69
+ | `--format <json\|table>` | Output format | `json` |
70
+ | `--api-key <key>` | Override stored API key | from config |
71
+ | `--base-url <url>` | Override API base URL | `https://api.lexq.io/api/v1/partners` |
72
+ | `--dry-run` | Preview the HTTP request without executing | off |
73
+ | `--verbose` | Show request/response details | off |
74
+ | `--no-color` | Disable colored output | off |
75
+
76
+ **Agent best practice:** Always use `--format json` (the default). Parse JSON output programmatically. Use `--format table` only when displaying to humans.
77
+
78
+ ## Command Groups
79
+
80
+ | Group | Commands | Description |
81
+ |---|---|---|
82
+ | `auth` | `login`, `logout`, `whoami` | Authentication |
83
+ | `status` | (root) | API health check |
84
+ | `groups` | `list`, `get`, `create`, `update`, `delete` + `ab-test start\|stop\|adjust` | Policy group CRUD + A/B testing |
85
+ | `versions` | `list`, `get`, `create`, `update`, `delete`, `clone` | Version CRUD |
86
+ | `rules` | `list`, `get`, `create`, `update`, `delete`, `reorder`, `toggle` | Rule CRUD |
87
+ | `facts` | `list`, `create`, `update`, `delete` | Fact definition CRUD |
88
+ | `deploy` | `publish`, `live`, `rollback`, `undeploy`, `history`, `detail`, `overview` | Deployment lifecycle |
89
+ | `analytics` | `dry-run`, `dry-run-compare`, `requirements`, `simulation start/status/list/cancel/export` | Testing & analysis |
90
+ | `history` | `list`, `get`, `stats` | Execution history |
91
+ | `integrations` | `list`, `get`, `save`, `delete`, `config-spec` | External integrations |
92
+ | `logs` | `list`, `get`, `action`, `bulk-action` | Failure log management |
93
+
94
+ ## Pagination
95
+
96
+ All list endpoints return a `PageResponse`:
97
+
98
+ ```json
99
+ {
100
+ "content": [...],
101
+ "totalElements": 42,
102
+ "totalPages": 3,
103
+ "pageNo": 0,
104
+ "pageSize": 20
105
+ }
106
+ ```
107
+
108
+ Use `--page` and `--size` to paginate. Pages are **0-indexed**.
109
+
110
+ ## Error Handling
111
+
112
+ API errors return:
113
+
114
+ ```json
115
+ {
116
+ "result": "ERROR",
117
+ "message": "Policy version not found.",
118
+ "code": "ENTITY_NOT_FOUND"
119
+ }
120
+ ```
121
+
122
+ **Common error codes and what to do:**
123
+
124
+ | Code | Meaning | Action |
125
+ |---|---|---|
126
+ | `ENTITY_NOT_FOUND` | Resource doesn't exist | Verify the ID. Run the corresponding `list` command. |
127
+ | `INVALID_INPUT` | Validation failed | Check required fields. Run `lexq analytics requirements` for fact requirements. |
128
+ | `CANNOT_MODIFY` | Version is not DRAFT | Clone the version to create a new DRAFT: `lexq versions clone` |
129
+ | `EMPTY_RULES` | Publish attempted with 0 rules | Add at least one rule before publishing. |
130
+ | `UNAUTHORIZED` | Invalid or missing API key | Run `lexq auth login` with a valid key. |
131
+
132
+ ## Important Conventions
133
+
134
+ 1. **Fact keys use `snake_case`.** Example: `payment_amount`, `customer_tier`. Always lowercase.
135
+ 2. **IDs are UUIDs.** Always copy the full ID from list/create output — do not guess.
136
+ 3. **Dates use ISO 8601.** Example: `2025-01-01T00:00:00Z`. Time zone is UTC.
137
+ 4. **JSON bodies via `--json`.** Most create/update commands accept `--json '<body>'` for the request body.
138
+ 5. **File input via `--file`.** Analytics commands accept `--file path/to/body.json` as an alternative to `--json`.
139
+ 6. **Confirmation prompts.** Destructive operations (delete, cancel, undeploy) prompt for confirmation. Use `--force` to skip in automation.
@@ -0,0 +1,279 @@
1
+ # LexQ CLI — Simulation & Testing
2
+
3
+ > **Prerequisite:** Read `lexq-shared/SKILL.md` first.
4
+
5
+ ## Overview
6
+
7
+ LexQ provides three levels of pre-deploy validation:
8
+
9
+ | Tool | Scope | When to Use |
10
+ |---|---|---|
11
+ | **Dry Run** | Single input | Quick validation of one scenario |
12
+ | **Dry Run Compare** | Single input, two versions | Side-by-side version comparison |
13
+ | **Simulation** | Batch (historical data) | Full regression test before deploy |
14
+
15
+ **Golden rule:** Always dry-run before publishing, always simulate before deploying to production.
16
+
17
+ ## 1. Requirements Analysis
18
+
19
+ Before testing, check what facts a version expects:
20
+
21
+ ```bash
22
+ lexq analytics requirements --group-id <gid> --version-id <vid>
23
+ ```
24
+
25
+ Response includes:
26
+
27
+ ```json
28
+ {
29
+ "groupId": "...",
30
+ "versionId": "...",
31
+ "versionNo": 3,
32
+ "requiredFacts": [
33
+ { "key": "payment_amount", "type": "NUMBER", "required": true, "usedBy": ["VIP Discount", "Premium Block"] },
34
+ { "key": "customer_tier", "type": "STRING", "required": true, "usedBy": ["VIP Discount"] }
35
+ ],
36
+ "exampleRequest": {
37
+ "facts": { "payment_amount": 0, "customer_tier": "" },
38
+ "context": {}
39
+ }
40
+ }
41
+ ```
42
+
43
+ **Always run this before dry-run.** Copy `exampleRequest.facts` as your starting template and fill in real values.
44
+
45
+ ## 2. Dry Run (Single Input)
46
+
47
+ Test a single set of facts against a version:
48
+
49
+ ```bash
50
+ lexq analytics dry-run --version-id <vid> --json '{
51
+ "facts": {
52
+ "payment_amount": 150000,
53
+ "customer_tier": "VIP"
54
+ }
55
+ }'
56
+ ```
57
+
58
+ ### Options
59
+
60
+ | Flag | Description | Default |
61
+ |---|---|---|
62
+ | `--debug` | Include execution traces (which rules matched, why) | `false` |
63
+ | `--mock` | Mock external calls (webhooks, integrations) | `false` |
64
+ | `--file <path>` | Read request body from file instead of `--json` | — |
65
+
66
+ ### Recommended: Always Use `--debug --mock`
67
+
68
+ ```bash
69
+ lexq analytics dry-run --version-id <vid> --debug --mock --json '{
70
+ "facts": { "payment_amount": 150000, "customer_tier": "VIP" }
71
+ }'
72
+ ```
73
+
74
+ ### Response Structure
75
+
76
+ ```json
77
+ {
78
+ "outputVariables": { "discount_amount": 15000 },
79
+ "executionTraces": [
80
+ {
81
+ "traceId": "...",
82
+ "ruleId": "...",
83
+ "ruleName": "VIP 10% Discount",
84
+ "matched": true,
85
+ "matchExpression": "(customer_tier == VIP AND payment_amount >= 100000)",
86
+ "generatedActions": [ { "type": "DISCOUNT", "parameters": { ... } } ]
87
+ }
88
+ ],
89
+ "decisionTraces": [
90
+ {
91
+ "ruleId": "...",
92
+ "ruleName": "VIP 10% Discount",
93
+ "status": "SELECTED",
94
+ "reasonCode": "FINAL_WINNER",
95
+ "reasonDetail": "..."
96
+ }
97
+ ],
98
+ "latencyMs": 12,
99
+ "versionNo": 3
100
+ }
101
+ ```
102
+
103
+ ### Reading Decision Traces
104
+
105
+ | Status | Meaning |
106
+ |---|---|
107
+ | `SELECTED` | Rule matched and its actions fired |
108
+ | `NO_MATCH` | Condition did not match the input |
109
+ | `NOT_SELECTED` | Matched but excluded by conflict resolution |
110
+ | `BLOCKED_MUTEX` | Blocked by mutex group constraint |
111
+ | `LOST_PRIORITY` | Lost to a higher-priority rule |
112
+ | `DROPPED_LIMIT` | Execution limit reached |
113
+ | `ERROR` | Rule evaluation failed |
114
+
115
+ ### Reading Reason Codes
116
+
117
+ | Code | Meaning |
118
+ |---|---|
119
+ | `FINAL_WINNER` | Successfully executed |
120
+ | `CONDITION_MISMATCH` | Input facts didn't satisfy the condition |
121
+ | `MUTEX_PRIORITY_LOST` | Another rule in the same mutex group had higher priority |
122
+ | `MUTEX_LIMIT_REACHED` | Mutex group's max rules already fired |
123
+ | `GROUP_LIMIT_REACHED` | Group's `executionLimit` reached |
124
+ | `ACTION_ERROR` | Action execution failed (e.g., webhook timeout) |
125
+
126
+ ## 3. Dry Run Compare
127
+
128
+ Compare how two versions evaluate the same input:
129
+
130
+ ```bash
131
+ lexq analytics dry-run-compare --json '{
132
+ "facts": { "payment_amount": 150000, "customer_tier": "VIP" },
133
+ "versionIdA": "<baselineVersionId>",
134
+ "versionIdB": "<candidateVersionId>"
135
+ }'
136
+ ```
137
+
138
+ Useful for validating that changes in a new version produce expected differences.
139
+
140
+ ## 4. Batch Simulation
141
+
142
+ Run a full regression test against historical execution data:
143
+
144
+ ### Start Simulation
145
+
146
+ ```bash
147
+ lexq analytics simulation start --json '{
148
+ "policyVersionId": "<targetVersionId>",
149
+ "dataset": {
150
+ "type": "HISTORICAL",
151
+ "source": "EXECUTION_LOGS",
152
+ "from": "2025-01-01",
153
+ "to": "2025-01-31"
154
+ },
155
+ "options": {
156
+ "includeRuleStats": true,
157
+ "maxRecords": 10000,
158
+ "baselinePolicyVersionId": "<currentLiveVersionId>",
159
+ "metricConfig": {
160
+ "targetVariable": "discount_amount",
161
+ "aggregationType": "SUM"
162
+ }
163
+ }
164
+ }'
165
+ ```
166
+
167
+ ### Dataset Types
168
+
169
+ | Type | Source | Description |
170
+ |---|---|---|
171
+ | `HISTORICAL` | `EXECUTION_LOGS` | Replay past executions from a date range |
172
+ | `MANUAL` | `REQUEST_BODY` | Provide `manualData` array in the request |
173
+ | `UPLOADED` | `S3_BUCKET` | Reference an uploaded dataset by `path` |
174
+
175
+ ### Check Status (Poll)
176
+
177
+ ```bash
178
+ lexq analytics simulation status --id <simulationId>
179
+ ```
180
+
181
+ Simulation is async. Poll until `status` is `COMPLETED` or `FAILED`.
182
+
183
+ | Status | Meaning |
184
+ |---|---|
185
+ | `PENDING` | Queued |
186
+ | `RUNNING` | In progress (`progress` field shows 0–100) |
187
+ | `COMPLETED` | Done — results available |
188
+ | `FAILED` | Error occurred |
189
+ | `CANCELLED` | Manually cancelled |
190
+
191
+ ### List Simulations
192
+
193
+ ```bash
194
+ lexq analytics simulation list --page 0 --size 20
195
+ lexq analytics simulation list --status COMPLETED --from 2025-01-01 --to 2025-01-31
196
+ ```
197
+
198
+ ### Cancel Simulation
199
+
200
+ ```bash
201
+ lexq analytics simulation cancel --id <simulationId>
202
+ lexq analytics simulation cancel --id <simulationId> --force
203
+ ```
204
+
205
+ ### Export Results
206
+
207
+ ```bash
208
+ lexq analytics simulation export --id <simulationId> --format json
209
+ lexq analytics simulation export --id <simulationId> --format csv --output results.csv
210
+ ```
211
+
212
+ ## Simulation Response (COMPLETED)
213
+
214
+ ```json
215
+ {
216
+ "simulationId": "...",
217
+ "status": "COMPLETED",
218
+ "summary": {
219
+ "totalRecords": 10000,
220
+ "matchedRecords": 8500,
221
+ "executionTimeMs": 3200,
222
+ "matchRate": 0.85
223
+ },
224
+ "metricSummary": {
225
+ "targetVariable": "discount_amount",
226
+ "aggregationType": "SUM",
227
+ "baselineValue": 5000000,
228
+ "simulatedValue": 4500000,
229
+ "delta": -500000,
230
+ "deltaPercentage": -10.0
231
+ },
232
+ "policyImpact": {
233
+ "policyVersionId": "...",
234
+ "comparison": {
235
+ "baselineVersionId": "...",
236
+ "difference": {
237
+ "matchedCountDelta": -200,
238
+ "matchedRateDelta": -0.02,
239
+ "metricValueDelta": -500000
240
+ }
241
+ }
242
+ },
243
+ "ruleStats": [
244
+ { "ruleId": "...", "ruleName": "VIP Discount", "matchedCount": 5000, "metricValue": 3000000 }
245
+ ]
246
+ }
247
+ ```
248
+
249
+ ## Agent Workflow: Validate Before Deploy
250
+
251
+ ```bash
252
+ # 1. Check what facts the version needs
253
+ lexq analytics requirements --group-id <gid> --version-id <vid>
254
+
255
+ # 2. Dry-run with representative inputs
256
+ lexq analytics dry-run --version-id <vid> --debug --mock --json '{
257
+ "facts": { "payment_amount": 150000, "customer_tier": "VIP" }
258
+ }'
259
+
260
+ # 3. If dry-run looks good, publish
261
+ lexq deploy publish --group-id <gid> --version-id <vid> --memo "Validated by agent"
262
+
263
+ # 4. Run simulation comparing new vs. current live version
264
+ lexq analytics simulation start --json '{
265
+ "policyVersionId": "<newVersionId>",
266
+ "dataset": { "type": "HISTORICAL", "source": "EXECUTION_LOGS", "from": "2025-01-01", "to": "2025-01-31" },
267
+ "options": {
268
+ "baselinePolicyVersionId": "<currentLiveVersionId>",
269
+ "includeRuleStats": true,
270
+ "metricConfig": { "targetVariable": "discount_amount", "aggregationType": "SUM" }
271
+ }
272
+ }'
273
+
274
+ # 5. Poll until complete
275
+ lexq analytics simulation status --id <simId>
276
+
277
+ # 6. If results acceptable, deploy
278
+ lexq deploy live --group-id <gid> --version-id <newVersionId> --memo "Simulation passed"
279
+ ```