@lexq/cli 0.1.40 → 0.1.41
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.
- package/AGENTS.md +34 -32
- package/CONTEXT.md +41 -47
- package/README.md +8 -6
- package/dist/index.js +119 -385
- package/dist/mcp/register.js +86 -166
- package/package.json +1 -1
- package/skills/lexq-execution/SKILL.md +120 -65
- package/skills/lexq-groups/SKILL.md +78 -38
- package/skills/lexq-recipes/SKILL.md +97 -193
- package/skills/lexq-rules/SKILL.md +105 -35
- package/skills/lexq-shared/SKILL.md +48 -28
- package/skills/lexq-simulation/SKILL.md +33 -33
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
7
|
Once policies are deployed, the engine evaluates incoming facts against live rules. This skill covers **observing**
|
|
8
|
-
production behavior: execution history, statistics, failure logs, and
|
|
8
|
+
production behavior: execution history, statistics, failure logs, and deployment state.
|
|
9
9
|
|
|
10
10
|
## 1. Execution History
|
|
11
11
|
|
|
@@ -28,12 +28,16 @@ Filter options:
|
|
|
28
28
|
|
|
29
29
|
### Execution Statuses
|
|
30
30
|
|
|
31
|
-
| Status | Meaning
|
|
32
|
-
|
|
33
|
-
| `SUCCESS` | At least one rule matched and actions executed
|
|
34
|
-
| `NO_MATCH` | No rules matched the
|
|
35
|
-
| `ERROR` | Engine error during evaluation
|
|
36
|
-
| `TIMEOUT` | Execution exceeded time limit
|
|
31
|
+
| Status | Meaning |
|
|
32
|
+
|------------|-----------------------------------------------------------------------------------------------|
|
|
33
|
+
| `SUCCESS` | At least one rule matched and actions executed |
|
|
34
|
+
| `NO_MATCH` | No rules matched — or the version was not evaluated at all (e.g. outside its effective dates) |
|
|
35
|
+
| `ERROR` | Engine error during evaluation |
|
|
36
|
+
| `TIMEOUT` | Execution exceeded time limit |
|
|
37
|
+
|
|
38
|
+
A version outside its effective date range is filtered before evaluation, so no per-rule trace is produced for it. If a
|
|
39
|
+
rule you expect never appears in `decisionTraces`, check the version's `effectiveFrom` / `effectiveTo` with
|
|
40
|
+
`lexq versions get`.
|
|
37
41
|
|
|
38
42
|
### Get Execution Detail
|
|
39
43
|
|
|
@@ -70,7 +74,16 @@ Use stats to monitor:
|
|
|
70
74
|
|
|
71
75
|
## 2. Failure Logs
|
|
72
76
|
|
|
73
|
-
|
|
77
|
+
Failure logs are a dead-letter record for background tasks that failed after the request returned.
|
|
78
|
+
Two task types exist:
|
|
79
|
+
|
|
80
|
+
| Task type | What failed |
|
|
81
|
+
|------------------------|------------------------------------------------------------------|
|
|
82
|
+
| `PLATFORM_WEBHOOK` | A platform event webhook delivery (`lexq webhook-subscriptions`) |
|
|
83
|
+
| `SCHEDULED_DEPLOYMENT` | A scheduled deployment that could not be armed or executed |
|
|
84
|
+
|
|
85
|
+
Policy execution failures do **not** land here — they surface in execution history with
|
|
86
|
+
status `ERROR`.
|
|
74
87
|
|
|
75
88
|
### List Failure Logs
|
|
76
89
|
|
|
@@ -80,14 +93,13 @@ lexq logs list --page 0 --size 20
|
|
|
80
93
|
|
|
81
94
|
Filter options:
|
|
82
95
|
|
|
83
|
-
| Flag | Description | Values
|
|
84
|
-
|
|
85
|
-
| `--
|
|
86
|
-
| `--
|
|
87
|
-
| `--
|
|
88
|
-
| `--
|
|
89
|
-
| `--
|
|
90
|
-
| `--end-date <date>` | End date (ISO) | `2025-01-31` |
|
|
96
|
+
| Flag | Description | Values |
|
|
97
|
+
|-----------------------|-----------------------------------------|--------------------------------------------|
|
|
98
|
+
| `--task-type <type>` | Task type | `PLATFORM_WEBHOOK`, `SCHEDULED_DEPLOYMENT` |
|
|
99
|
+
| `--status <status>` | Log status | `PENDING`, `RESOLVED`, `IGNORED` |
|
|
100
|
+
| `--keyword <kw>` | Search in refId, refSubId, errorMessage | any string |
|
|
101
|
+
| `--start-date <date>` | Start date (ISO) | `2025-01-01` |
|
|
102
|
+
| `--end-date <date>` | End date (ISO) | `2025-01-31` |
|
|
91
103
|
|
|
92
104
|
### Get Failure Log Detail
|
|
93
105
|
|
|
@@ -95,102 +107,142 @@ Filter options:
|
|
|
95
107
|
lexq logs get --id <logId>
|
|
96
108
|
```
|
|
97
109
|
|
|
98
|
-
|
|
110
|
+
Includes the original payload and error message. Use it to diagnose before marking the log.
|
|
99
111
|
|
|
100
|
-
|
|
101
|
-
lexq logs action --id <logId> --action RETRY
|
|
102
|
-
```
|
|
112
|
+
### Mark a Log
|
|
103
113
|
|
|
104
|
-
|
|
114
|
+
There is no retry action — the engine does not re-execute a failed task on request. Fix the cause
|
|
115
|
+
at the source (webhook endpoint, version state), then mark the log.
|
|
105
116
|
|
|
106
117
|
```bash
|
|
107
|
-
lexq logs action --id <logId> --action RESOLVE
|
|
118
|
+
lexq logs action --id <logId> --action RESOLVE # cause was fixed
|
|
119
|
+
lexq logs action --id <logId> --action IGNORE # does not need fixing
|
|
108
120
|
```
|
|
109
121
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
lexq logs action --id <logId> --action IGNORE
|
|
114
|
-
```
|
|
122
|
+
Both remove the log from `PENDING`; they differ only in recorded intent.
|
|
115
123
|
|
|
116
124
|
### Bulk Operations
|
|
117
125
|
|
|
118
126
|
```bash
|
|
119
|
-
lexq logs bulk-action --ids "id1,id2,id3" --action RETRY
|
|
120
127
|
lexq logs bulk-action --ids "id1,id2,id3" --action RESOLVE
|
|
128
|
+
lexq logs bulk-action --ids "id4,id5" --action IGNORE
|
|
121
129
|
```
|
|
122
130
|
|
|
123
|
-
## 3.
|
|
131
|
+
## 3. Deployment Monitoring
|
|
124
132
|
|
|
125
|
-
|
|
133
|
+
### Deployment Overview
|
|
126
134
|
|
|
127
|
-
|
|
135
|
+
See all groups' deployment status at a glance:
|
|
128
136
|
|
|
129
137
|
```bash
|
|
130
|
-
lexq
|
|
138
|
+
lexq deploy overview
|
|
131
139
|
```
|
|
132
140
|
|
|
133
|
-
|
|
141
|
+
Returns an array with each group's current version, last deployment type, and deployer.
|
|
142
|
+
|
|
143
|
+
### Deployment History
|
|
134
144
|
|
|
135
145
|
```bash
|
|
136
|
-
lexq
|
|
146
|
+
lexq deploy history --page 0 --size 20
|
|
147
|
+
lexq deploy history --group-id <gid>
|
|
148
|
+
lexq deploy history --types DEPLOY,ROLLBACK --start-date 2025-01-01
|
|
137
149
|
```
|
|
138
150
|
|
|
139
|
-
###
|
|
140
|
-
|
|
141
|
-
Shows available integration types and their required configuration fields:
|
|
151
|
+
### Deployment Detail
|
|
142
152
|
|
|
143
153
|
```bash
|
|
144
|
-
lexq
|
|
154
|
+
lexq deploy detail --id <deploymentId>
|
|
145
155
|
```
|
|
146
156
|
|
|
147
|
-
|
|
157
|
+
Includes snapshot hash verification (`hashValid` field) to detect if a version was modified after deployment.
|
|
158
|
+
|
|
159
|
+
### Scheduled Deployment
|
|
160
|
+
|
|
161
|
+
A version with a future `effectiveFrom` can be armed to deploy itself at that time.
|
|
148
162
|
|
|
149
163
|
```bash
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
164
|
+
# Arm — the version must be ACTIVE (published) with a future effective start
|
|
165
|
+
lexq deploy schedule --group-id <gid> --version-id <vid> --memo "Q4 pricing"
|
|
166
|
+
|
|
167
|
+
# List all schedules (PENDING, EXECUTED, CANCELED, FAILED)
|
|
168
|
+
lexq deploy schedules --format table
|
|
169
|
+
|
|
170
|
+
# Cancel the pending schedule (the version itself is untouched)
|
|
171
|
+
lexq deploy unschedule --group-id <gid> --force
|
|
156
172
|
```
|
|
157
173
|
|
|
158
|
-
|
|
174
|
+
One pending schedule per group. The scheduler deploys within one tick (≤60s) of the effective
|
|
175
|
+
start. A manual deploy, rollback, undeploy, A/B test start, or group archive **cancels** the
|
|
176
|
+
pending schedule — the cancellation reason is recorded in the schedule ledger.
|
|
177
|
+
|
|
178
|
+
The snapshot hash is sealed at scheduling time. If the version changes before the effective start,
|
|
179
|
+
the scheduled deploy fails with `HASH_MISMATCH` rather than deploying something unexpected.
|
|
159
180
|
|
|
160
|
-
|
|
181
|
+
## 4. Decision Provenance
|
|
182
|
+
|
|
183
|
+
Every execution is sealed with a `traceId`. Provenance answers "why did this decision happen"
|
|
184
|
+
deterministically — which rules fired, which lost, and to what.
|
|
161
185
|
|
|
162
186
|
```bash
|
|
163
|
-
lexq
|
|
164
|
-
lexq integrations delete --id <integrationId> --force
|
|
187
|
+
lexq provenance get --trace-id <traceId>
|
|
165
188
|
```
|
|
166
189
|
|
|
167
|
-
|
|
190
|
+
Returns the decision, per-rule reason codes (`FINAL_WINNER`, `CONDITION_MISMATCH`, `MUTEX_PRIORITY_LOST`,
|
|
191
|
+
`GROUP_LIMIT_REACHED`, …), and the sealed version snapshot hash.
|
|
168
192
|
|
|
169
|
-
|
|
193
|
+
A rule that lost conflict resolution has status `BLOCKED` — unrelated to the `BLOCK` action, which writes the
|
|
194
|
+
`is_blocked` fact while its own rule stays `SELECTED`.
|
|
170
195
|
|
|
171
|
-
|
|
196
|
+
### PII Reveal Audit
|
|
197
|
+
|
|
198
|
+
Facts marked `isPii` are masked on every read surface. Unmasking is possible only in the console
|
|
199
|
+
and every reveal is recorded.
|
|
172
200
|
|
|
173
201
|
```bash
|
|
174
|
-
lexq
|
|
202
|
+
lexq provenance reveal-audits
|
|
175
203
|
```
|
|
176
204
|
|
|
177
|
-
Returns
|
|
205
|
+
Returns who revealed which fact of which trace, and when.
|
|
178
206
|
|
|
179
|
-
|
|
207
|
+
## 5. Decision Replay
|
|
208
|
+
|
|
209
|
+
Re-evaluate past executions against a candidate version to see what would have changed.
|
|
180
210
|
|
|
181
211
|
```bash
|
|
182
|
-
|
|
183
|
-
lexq
|
|
184
|
-
|
|
212
|
+
# Single decision
|
|
213
|
+
lexq replay decision --trace-id <traceId> --version-id <candidateVid>
|
|
214
|
+
|
|
215
|
+
# A date window, as an async job
|
|
216
|
+
lexq replay start --version-id <candidateVid> --from 2025-01-01 --to 2025-01-31
|
|
217
|
+
# --max-records caps the sample (hard cap 50k)
|
|
218
|
+
lexq replay get --id <jobId>
|
|
219
|
+
lexq replay list
|
|
220
|
+
lexq replay cancel --id <jobId>
|
|
185
221
|
```
|
|
186
222
|
|
|
187
|
-
|
|
223
|
+
Replay reports whether the outcome is `DETERMINISTIC` or `REPLAY_MAY_DIFFER` — the latter when the
|
|
224
|
+
original execution depended on values the replay cannot reproduce.
|
|
225
|
+
|
|
226
|
+
## 6. Latency Profile
|
|
227
|
+
|
|
228
|
+
Per-rule latency distribution for a policy group.
|
|
188
229
|
|
|
189
230
|
```bash
|
|
190
|
-
lexq
|
|
231
|
+
lexq profile <groupId>
|
|
232
|
+
|
|
233
|
+
# Single-rule detail — distributions + 60s window series
|
|
234
|
+
lexq profile <groupId> --rule <ruleId>
|
|
235
|
+
|
|
236
|
+
# Defaults: live version, last 24h, cache HIT
|
|
237
|
+
lexq profile <groupId> --version <vid> --cache MISS \
|
|
238
|
+
--from 2026-07-01T00:00:00Z --to 2026-08-01T00:00:00Z
|
|
191
239
|
```
|
|
192
240
|
|
|
193
|
-
|
|
241
|
+
`--from` / `--to` are ISO-8601 **instants** here (`2026-07-01T00:00:00Z`), unlike `replay start`
|
|
242
|
+
which takes `yyyy-MM-dd` dates.
|
|
243
|
+
|
|
244
|
+
`p50` / `p95` / `p99` are `null` when the sample is under 100 — the engine reports insufficient
|
|
245
|
+
data rather than inventing a number. `n` is always present.
|
|
194
246
|
|
|
195
247
|
## Agent Monitoring Workflow
|
|
196
248
|
|
|
@@ -201,13 +253,16 @@ lexq history stats
|
|
|
201
253
|
# 2. If failure rate is high, investigate
|
|
202
254
|
lexq history list --status ERROR --page 0 --size 10
|
|
203
255
|
|
|
204
|
-
# 3.
|
|
256
|
+
# 3. For a specific bad decision, get the deterministic why
|
|
257
|
+
lexq provenance get --trace-id <traceId>
|
|
258
|
+
|
|
259
|
+
# 4. Check for system failures
|
|
205
260
|
lexq logs list --status PENDING --page 0 --size 10
|
|
206
261
|
|
|
207
|
-
#
|
|
208
|
-
lexq logs
|
|
262
|
+
# 5. Inspect and mark
|
|
263
|
+
lexq logs get --id <logId>
|
|
209
264
|
lexq logs action --id <logId> --action RESOLVE
|
|
210
265
|
|
|
211
|
-
#
|
|
266
|
+
# 6. Verify deployment integrity
|
|
212
267
|
lexq deploy overview
|
|
213
268
|
```
|
|
@@ -4,19 +4,21 @@
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
A **Policy Group** is the top-level container. It holds versions (each containing rules), manages deployment state, and
|
|
7
|
+
A **Policy Group** is the top-level container. It holds versions (each containing rules), manages deployment state, and
|
|
8
|
+
controls conflict resolution when multiple groups interact.
|
|
8
9
|
|
|
9
10
|
## Status Lifecycle
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
| From | To | Reversible |
|
|
13
|
+
|------------|------------|-----------------------------------|
|
|
14
|
+
| `ACTIVE` | `DISABLED` | yes — set status back to `ACTIVE` |
|
|
15
|
+
| `DISABLED` | `ACTIVE` | — |
|
|
16
|
+
| `ACTIVE` | `ARCHIVED` | **no** |
|
|
17
|
+
| `DISABLED` | `ARCHIVED` | **no** |
|
|
16
18
|
|
|
17
|
-
- **ACTIVE
|
|
18
|
-
- **DISABLED
|
|
19
|
-
- **ARCHIVED
|
|
19
|
+
- **ACTIVE** — executions are processed.
|
|
20
|
+
- **DISABLED** — all executions are blocked. Use for emergency stop.
|
|
21
|
+
- **ARCHIVED** — removed from execution. Reached only through `lexq groups delete`, not by setting `status` directly.
|
|
20
22
|
|
|
21
23
|
## CRUD Commands
|
|
22
24
|
|
|
@@ -40,36 +42,49 @@ Returns full detail including `activationMode`, `activationStrategy`, `execution
|
|
|
40
42
|
lexq groups create --json '{
|
|
41
43
|
"name": "discount-policy",
|
|
42
44
|
"description": "VIP discount rules",
|
|
43
|
-
"priority": 0,
|
|
44
45
|
"activationMode": "NONE",
|
|
45
|
-
"activationStrategy": "
|
|
46
|
+
"activationStrategy": "HIGHEST_PRIORITY",
|
|
46
47
|
"status": "ACTIVE"
|
|
47
48
|
}'
|
|
48
49
|
```
|
|
49
50
|
|
|
50
|
-
**Required
|
|
51
|
+
**Required field:** `name`
|
|
52
|
+
|
|
53
|
+
`priority` is assigned by the server, not by you — new groups are appended last. Change the order
|
|
54
|
+
with `lexq groups reorder`. Priorities are 1-based (1 is highest).
|
|
51
55
|
|
|
52
56
|
**Optional fields with defaults:**
|
|
53
57
|
|
|
54
|
-
| Field
|
|
55
|
-
|
|
56
|
-
| `activationMode`
|
|
57
|
-
| `activationStrategy` | `
|
|
58
|
-
| `executionLimit`
|
|
59
|
-
| `activationGroup`
|
|
60
|
-
| `status`
|
|
58
|
+
| Field | Default | Description |
|
|
59
|
+
|----------------------|--------------------|----------------------------------------------------|
|
|
60
|
+
| `activationMode` | `NONE` | Conflict resolution mode |
|
|
61
|
+
| `activationStrategy` | `HIGHEST_PRIORITY` | Strategy within the mode. Currently the only value |
|
|
62
|
+
| `executionLimit` | `null` | Max rules that can fire |
|
|
63
|
+
| `activationGroup` | `null` | Logical group for cross-group conflict resolution |
|
|
64
|
+
| `status` | `ACTIVE` | Initial status |
|
|
61
65
|
|
|
62
66
|
### Update Group
|
|
63
67
|
|
|
64
68
|
```bash
|
|
65
69
|
lexq groups update --id <groupId> --json '{
|
|
66
70
|
"name": "updated-discount-policy",
|
|
67
|
-
"
|
|
71
|
+
"description": "Updated description"
|
|
68
72
|
}'
|
|
69
73
|
```
|
|
70
74
|
|
|
71
75
|
Only include fields you want to change. Omitted fields are not modified.
|
|
72
76
|
|
|
77
|
+
### Reorder Groups
|
|
78
|
+
|
|
79
|
+
Priorities are **tenant-wide**, not per activation group. Pass group IDs in desired order; the
|
|
80
|
+
server assigns 1, 2, 3, … (1…N continuous):
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
lexq groups reorder --group-ids "<gid_A>,<gid_B>,<gid_C>"
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`activationGroup` is not affected — reorder changes priority only.
|
|
87
|
+
|
|
73
88
|
### Delete Group
|
|
74
89
|
|
|
75
90
|
```bash
|
|
@@ -78,27 +93,45 @@ lexq groups delete --id <groupId>
|
|
|
78
93
|
lexq groups delete --id <groupId> --force
|
|
79
94
|
```
|
|
80
95
|
|
|
81
|
-
|
|
96
|
+
**`delete` archives — it does not erase.** The group becomes `ARCHIVED` and stops executing;
|
|
97
|
+
versions, rules, and history are retained for audit. Deleting an already-archived group is a
|
|
98
|
+
no-op.
|
|
99
|
+
|
|
100
|
+
Two conditions block it:
|
|
101
|
+
|
|
102
|
+
| Condition | What to do first |
|
|
103
|
+
|------------------------|-----------------------------------------------------|
|
|
104
|
+
| The group is deployed | `lexq deploy undeploy --group-id <gid>` |
|
|
105
|
+
| An A/B test is running | `lexq groups ab-test stop --group-id <gid> --force` |
|
|
106
|
+
|
|
107
|
+
Archiving cancels any pending scheduled deployment and closes the priority gap — remaining groups
|
|
108
|
+
are renumbered 1…N.
|
|
82
109
|
|
|
83
110
|
## Conflict Resolution
|
|
84
111
|
|
|
85
112
|
### Activation Mode (across groups in the same `activationGroup`)
|
|
86
113
|
|
|
87
|
-
| Mode
|
|
88
|
-
|
|
89
|
-
| `NONE`
|
|
90
|
-
| `EXCLUSIVE` | Only one group wins within the activation group.
|
|
91
|
-
| `MAX_N`
|
|
114
|
+
| Mode | Behavior |
|
|
115
|
+
|-------------|--------------------------------------------------------------------|
|
|
116
|
+
| `NONE` | All matching rules fire. No conflict resolution. |
|
|
117
|
+
| `EXCLUSIVE` | Only one group wins within the activation group. |
|
|
118
|
+
| `MAX_N` | Up to `executionLimit` groups fire. Omit it and the server sets 2. |
|
|
92
119
|
|
|
93
120
|
### Activation Strategy
|
|
94
121
|
|
|
95
|
-
| Strategy
|
|
96
|
-
|
|
97
|
-
| `
|
|
98
|
-
| `HIGHEST_PRIORITY` | Lowest priority number wins (0 = highest). |
|
|
99
|
-
| `MAX_BENEFIT` | Group producing the largest action value wins. |
|
|
122
|
+
| Strategy | Behavior |
|
|
123
|
+
|--------------------|--------------------------------------------------------------------------|
|
|
124
|
+
| `HIGHEST_PRIORITY` | Lowest priority number wins (1 is highest). Currently the only strategy. |
|
|
100
125
|
|
|
101
|
-
**Constraint:** All groups sharing the same `activationGroup` **must** use identical
|
|
126
|
+
**Constraint:** All groups sharing the same `activationGroup` **must** use identical
|
|
127
|
+
`activationMode` and `activationStrategy`. The API rejects mismatches with a `P-` error.
|
|
128
|
+
|
|
129
|
+
Groups are selected by the order you set, not by comparing action values. `FIRST_MATCH` and
|
|
130
|
+
`MAX_BENEFIT` were removed on 2026-08-01 — the former resolved identically to
|
|
131
|
+
`HIGHEST_PRIORITY` (candidates are evaluated in priority order, so "first match" *is* "lowest
|
|
132
|
+
priority number"), and the latter compared post-action values as scores, which made a 20%
|
|
133
|
+
discount lose to a 10% discount. The engine cannot know which direction is "better" for your
|
|
134
|
+
domain.
|
|
102
135
|
|
|
103
136
|
### Example: Exclusive Discount Groups
|
|
104
137
|
|
|
@@ -106,7 +139,6 @@ lexq groups delete --id <groupId> --force
|
|
|
106
139
|
# Only one of these can fire per execution
|
|
107
140
|
lexq groups create --json '{
|
|
108
141
|
"name": "vip-discount",
|
|
109
|
-
"priority": 0,
|
|
110
142
|
"activationGroup": "discounts",
|
|
111
143
|
"activationMode": "EXCLUSIVE",
|
|
112
144
|
"activationStrategy": "HIGHEST_PRIORITY"
|
|
@@ -114,11 +146,13 @@ lexq groups create --json '{
|
|
|
114
146
|
|
|
115
147
|
lexq groups create --json '{
|
|
116
148
|
"name": "seasonal-discount",
|
|
117
|
-
"priority": 1,
|
|
118
149
|
"activationGroup": "discounts",
|
|
119
150
|
"activationMode": "EXCLUSIVE",
|
|
120
151
|
"activationStrategy": "HIGHEST_PRIORITY"
|
|
121
152
|
}'
|
|
153
|
+
|
|
154
|
+
# Groups are appended in creation order. Set it explicitly if it matters:
|
|
155
|
+
# lexq groups reorder --group-ids "<vipGid>,<seasonalGid>"
|
|
122
156
|
```
|
|
123
157
|
|
|
124
158
|
## A/B Testing
|
|
@@ -128,11 +162,14 @@ Split traffic between the current live version and a test version.
|
|
|
128
162
|
### Start A/B Test
|
|
129
163
|
|
|
130
164
|
```bash
|
|
131
|
-
lexq groups ab-test start --group-id <groupId> --version-id <
|
|
165
|
+
lexq groups ab-test start --group-id <groupId> --version-id <activeVersionId> --traffic-rate 30
|
|
132
166
|
```
|
|
133
167
|
|
|
134
168
|
`--traffic-rate` is the percentage (1–99) of traffic routed to the test version.
|
|
135
169
|
|
|
170
|
+
The test version must be `ACTIVE` (published) and different from the live version. Starting a test cancels any pending
|
|
171
|
+
scheduled deployment for the group.
|
|
172
|
+
|
|
136
173
|
### Adjust Traffic
|
|
137
174
|
|
|
138
175
|
```bash
|
|
@@ -156,7 +193,7 @@ This reverts all traffic to the main version. The test version remains ACTIVE bu
|
|
|
156
193
|
2. Publish v2: lexq deploy publish --group-id <gid> --version-id <v2id>
|
|
157
194
|
3. Start A/B: lexq groups ab-test start --group-id <gid> --version-id <v2id> --traffic-rate 10
|
|
158
195
|
4. Monitor: lexq history stats (compare metrics)
|
|
159
|
-
5. Adjust traffic gradually: 10% → 30% → 50%
|
|
196
|
+
5. Adjust traffic gradually: 10% → 30% → 50%
|
|
160
197
|
6. Promote winner: lexq deploy live --group-id <gid> --version-id <v2id>
|
|
161
198
|
7. Stop test: lexq groups ab-test stop --group-id <gid> --force
|
|
162
199
|
```
|
|
@@ -168,10 +205,13 @@ This reverts all traffic to the main version. The test version remains ACTIVE bu
|
|
|
168
205
|
Always list existing groups first to avoid duplicates:
|
|
169
206
|
|
|
170
207
|
```bash
|
|
171
|
-
lexq groups list --
|
|
172
|
-
lexq groups create --json '
|
|
208
|
+
lexq groups list --size 100
|
|
209
|
+
lexq groups create --json '{"name": "discount-policy"}'
|
|
173
210
|
```
|
|
174
211
|
|
|
212
|
+
Group names are unique per tenant — a duplicate is rejected, not silently created. Listing first
|
|
213
|
+
lets you reuse the existing group instead of handling the error.
|
|
214
|
+
|
|
175
215
|
### Emergency Stop
|
|
176
216
|
|
|
177
217
|
```bash
|