@lexq/cli 1.1.0 → 1.1.1
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/dist/index.js +20 -10
- package/dist/mcp/register.js +17 -9
- package/package.json +1 -1
- package/skills/lexq-recipes/SKILL.md +4 -2
- package/skills/lexq-rules/SKILL.md +11 -4
package/dist/index.js
CHANGED
|
@@ -1328,7 +1328,9 @@ ${data.totalElements} total \xB7 page ${data.pageNo + 1}/${data.totalPages}`);
|
|
|
1328
1328
|
dedent6`
|
|
1329
1329
|
|
|
1330
1330
|
Facts used in a version's rules that have no definition yet (read-only).
|
|
1331
|
-
|
|
1331
|
+
Keys a rule only reads do not block publish/deploy; register them to enable
|
|
1332
|
+
validation. A SET_FACT or MUTATE_FACT targetVar must already be registered:
|
|
1333
|
+
saving or publishing fails with ACT-032 otherwise.
|
|
1332
1334
|
|
|
1333
1335
|
Example:
|
|
1334
1336
|
$ lexq facts unregistered --group-id <gid> --version-id <vid> --format table
|
|
@@ -3842,7 +3844,12 @@ function registerRuleTools(server, callApi) {
|
|
|
3842
3844
|
If a required key is missing, ask the user to confirm the type, isRequired, and description
|
|
3843
3845
|
before calling lexq_facts_create — registering facts enables type validation, Console UI
|
|
3844
3846
|
autocomplete, and the dry-run requirements analyzer.
|
|
3845
|
-
|
|
3847
|
+
|
|
3848
|
+
An action's targetVar (SET_FACT, MUTATE_FACT) must be a registered fact. Saving or
|
|
3849
|
+
publishing a rule whose targetVar is not registered fails with ACT-032, so register it
|
|
3850
|
+
with lexq_facts_create first. Keys a rule only reads (condition fields, refVar) may stay
|
|
3851
|
+
unregistered.
|
|
3852
|
+
|
|
3846
3853
|
After saving, lexq_facts_unregistered lists any keys this version references but has not
|
|
3847
3854
|
defined (non-blocking, version-wide) — use it to decide what to register.
|
|
3848
3855
|
|
|
@@ -3871,8 +3878,9 @@ function registerRuleTools(server, callApi) {
|
|
|
3871
3878
|
|
|
3872
3879
|
Action parameter schemas:
|
|
3873
3880
|
- MUTATE_FACT: { targetVar: string, operator: "ASSIGN"|"ADD"|"SUB"|"MUL"|"DIV", method: "PERCENTAGE"|"AMOUNT", operand: number, refVar?: string, rounding?: RoundingOption }
|
|
3874
|
-
targetVar is the fact this action reads and writes. It must
|
|
3875
|
-
|
|
3881
|
+
targetVar is the fact this action reads and writes. It must be a registered fact
|
|
3882
|
+
(ACT-032 otherwise), and the request must send it (P-015 otherwise). Its value must be
|
|
3883
|
+
a number when the action runs.
|
|
3876
3884
|
A missing required fact throws (no 0 default).
|
|
3877
3885
|
operand is the arithmetic operand; the unit is dictated by method (percent when
|
|
3878
3886
|
PERCENTAGE, absolute amount when AMOUNT). Ranges are not constrained — negative values
|
|
@@ -3890,8 +3898,10 @@ function registerRuleTools(server, callApi) {
|
|
|
3890
3898
|
DIV targetVar /= operand | invalid
|
|
3891
3899
|
Constraints: DIV + PERCENTAGE is invalid (use MUL with the inverse). DIV + AMOUNT
|
|
3892
3900
|
requires operand !== 0.
|
|
3893
|
-
- SET_FACT: { targetVar: string, value: string|number|boolean }
|
|
3894
|
-
|
|
3901
|
+
- SET_FACT: { targetVar: string, value: string|number|boolean } targetVar must be a
|
|
3902
|
+
registered fact (ACT-032 otherwise). The request does not have to send it: SET_FACT is
|
|
3903
|
+
the only action that can write a key absent from the input facts. MUTATE_FACT requires
|
|
3904
|
+
its target to be present in the input facts.
|
|
3895
3905
|
- BLOCK: { reason: string } Records a rejection decision. It does NOT halt rule execution —
|
|
3896
3906
|
subsequent actions and subsequent winning rules still run. Enforcement is the caller's
|
|
3897
3907
|
responsibility; the decision surfaces as the isBlocked fact.
|
|
@@ -3916,7 +3926,7 @@ function registerRuleTools(server, callApi) {
|
|
|
3916
3926
|
{
|
|
3917
3927
|
title: "Update Rule",
|
|
3918
3928
|
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
3919
|
-
description: `Update an existing rule in a DRAFT version. Only provided fields are changed. A new condition tree must stay within ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes) and ${MAX_CONDITION_DEPTH} levels of nesting below the root.`,
|
|
3929
|
+
description: `Update an existing rule in a DRAFT version. Only provided fields are changed. A new condition tree must stay within ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes) and ${MAX_CONDITION_DEPTH} levels of nesting below the root. Saving re-checks every action in the rule, including ones you did not change, and fails with ACT-032 if any action's targetVar is not a registered fact.`,
|
|
3920
3930
|
inputSchema: z4.object({
|
|
3921
3931
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
3922
3932
|
versionId: z4.string().uuid().describe("Version ID"),
|
|
@@ -4095,7 +4105,7 @@ function registerFactTools(server, callApi) {
|
|
|
4095
4105
|
{
|
|
4096
4106
|
title: "Get Action Runtime Fact Metadata",
|
|
4097
4107
|
annotations: { readOnlyHint: true },
|
|
4098
|
-
description: "Retrieve runtime fact requirements per Action type. For each Action, shows which input facts must be present in the execution payload \u2014 e.g. MUTATE_FACT always requires its targetVar fact, plus refVar when one is specified. The factRequired flag describes the FACT, not the parameter: refVar is an optional parameter, but if you specify it the named fact must exist. A required fact absent at runtime throws \u2014 the engine never defaults to 0.
|
|
4108
|
+
description: "Retrieve runtime fact requirements per Action type. For each Action, shows which input facts must be present in the execution payload \u2014 e.g. MUTATE_FACT always requires its targetVar fact, plus refVar when one is specified. The factRequired flag describes the FACT, not the parameter: refVar is an optional parameter, but if you specify it the named fact must exist. A required fact absent at runtime throws \u2014 the engine never defaults to 0. These facts must be sent in the request (P-015 otherwise), even when an earlier action in the same rule writes them. SET_FACT requires no input fact: it is the only action that can write a key the request did not send, and its targetVar must be a registered fact (ACT-032). Static data, safe to cache in-session.",
|
|
4099
4109
|
inputSchema: z5.object({})
|
|
4100
4110
|
},
|
|
4101
4111
|
async () => callApi("GET", "schema/action-metadata")
|
|
@@ -4105,7 +4115,7 @@ function registerFactTools(server, callApi) {
|
|
|
4105
4115
|
{
|
|
4106
4116
|
title: "List Unregistered Facts",
|
|
4107
4117
|
annotations: { readOnlyHint: true },
|
|
4108
|
-
description: "List facts referenced by a version's rules but not yet defined (read-only
|
|
4118
|
+
description: "List facts referenced by a version's rules but not yet defined (read-only). Keys that rules only read do not block publish/deploy; a rule whose action targetVar is not a registered fact is rejected at save and publish with ACT-032. Version-wide: covers every rule in the version. Each entry carries the inferred type, suggested name, and where it is referenced (condition/action). Register them with lexq_facts_create to enable type validation and the dry-run requirements analyzer.",
|
|
4109
4119
|
inputSchema: z5.object({
|
|
4110
4120
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
4111
4121
|
versionId: z5.string().uuid().describe("Version ID")
|
|
@@ -4138,7 +4148,7 @@ function registerDeployTools(server, callApi) {
|
|
|
4138
4148
|
{
|
|
4139
4149
|
title: "Publish Version",
|
|
4140
4150
|
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
4141
|
-
description: `Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts
|
|
4151
|
+
description: `Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts that rules only read do not block publishing; call lexq_facts_unregistered first to review them. Publishing fails if an action's targetVar is not a registered fact (ACT-032), if the version's compiled rules exceed ${MAX_SNAPSHOT_BYTES / 1024} KB, or if its effective end has already passed (P-058); move the end into the future with lexq_versions_update first.`,
|
|
4142
4152
|
inputSchema: z6.object({
|
|
4143
4153
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
4144
4154
|
versionId: z6.string().uuid().describe("Version ID to publish"),
|
package/dist/mcp/register.js
CHANGED
|
@@ -409,7 +409,12 @@ function registerRuleTools(server, callApi) {
|
|
|
409
409
|
If a required key is missing, ask the user to confirm the type, isRequired, and description
|
|
410
410
|
before calling lexq_facts_create — registering facts enables type validation, Console UI
|
|
411
411
|
autocomplete, and the dry-run requirements analyzer.
|
|
412
|
-
|
|
412
|
+
|
|
413
|
+
An action's targetVar (SET_FACT, MUTATE_FACT) must be a registered fact. Saving or
|
|
414
|
+
publishing a rule whose targetVar is not registered fails with ACT-032, so register it
|
|
415
|
+
with lexq_facts_create first. Keys a rule only reads (condition fields, refVar) may stay
|
|
416
|
+
unregistered.
|
|
417
|
+
|
|
413
418
|
After saving, lexq_facts_unregistered lists any keys this version references but has not
|
|
414
419
|
defined (non-blocking, version-wide) — use it to decide what to register.
|
|
415
420
|
|
|
@@ -438,8 +443,9 @@ function registerRuleTools(server, callApi) {
|
|
|
438
443
|
|
|
439
444
|
Action parameter schemas:
|
|
440
445
|
- MUTATE_FACT: { targetVar: string, operator: "ASSIGN"|"ADD"|"SUB"|"MUL"|"DIV", method: "PERCENTAGE"|"AMOUNT", operand: number, refVar?: string, rounding?: RoundingOption }
|
|
441
|
-
targetVar is the fact this action reads and writes. It must
|
|
442
|
-
|
|
446
|
+
targetVar is the fact this action reads and writes. It must be a registered fact
|
|
447
|
+
(ACT-032 otherwise), and the request must send it (P-015 otherwise). Its value must be
|
|
448
|
+
a number when the action runs.
|
|
443
449
|
A missing required fact throws (no 0 default).
|
|
444
450
|
operand is the arithmetic operand; the unit is dictated by method (percent when
|
|
445
451
|
PERCENTAGE, absolute amount when AMOUNT). Ranges are not constrained — negative values
|
|
@@ -457,8 +463,10 @@ function registerRuleTools(server, callApi) {
|
|
|
457
463
|
DIV targetVar /= operand | invalid
|
|
458
464
|
Constraints: DIV + PERCENTAGE is invalid (use MUL with the inverse). DIV + AMOUNT
|
|
459
465
|
requires operand !== 0.
|
|
460
|
-
- SET_FACT: { targetVar: string, value: string|number|boolean }
|
|
461
|
-
|
|
466
|
+
- SET_FACT: { targetVar: string, value: string|number|boolean } targetVar must be a
|
|
467
|
+
registered fact (ACT-032 otherwise). The request does not have to send it: SET_FACT is
|
|
468
|
+
the only action that can write a key absent from the input facts. MUTATE_FACT requires
|
|
469
|
+
its target to be present in the input facts.
|
|
462
470
|
- BLOCK: { reason: string } Records a rejection decision. It does NOT halt rule execution —
|
|
463
471
|
subsequent actions and subsequent winning rules still run. Enforcement is the caller's
|
|
464
472
|
responsibility; the decision surfaces as the isBlocked fact.
|
|
@@ -483,7 +491,7 @@ function registerRuleTools(server, callApi) {
|
|
|
483
491
|
{
|
|
484
492
|
title: "Update Rule",
|
|
485
493
|
annotations: { readOnlyHint: false, destructiveHint: true },
|
|
486
|
-
description: `Update an existing rule in a DRAFT version. Only provided fields are changed. A new condition tree must stay within ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes) and ${MAX_CONDITION_DEPTH} levels of nesting below the root.`,
|
|
494
|
+
description: `Update an existing rule in a DRAFT version. Only provided fields are changed. A new condition tree must stay within ${MAX_CONDITIONS_PER_RULE} conditions (SINGLE nodes) and ${MAX_CONDITION_DEPTH} levels of nesting below the root. Saving re-checks every action in the rule, including ones you did not change, and fails with ACT-032 if any action's targetVar is not a registered fact.`,
|
|
487
495
|
inputSchema: z4.object({
|
|
488
496
|
groupId: z4.string().uuid().describe("Policy group ID"),
|
|
489
497
|
versionId: z4.string().uuid().describe("Version ID"),
|
|
@@ -666,7 +674,7 @@ function registerFactTools(server, callApi) {
|
|
|
666
674
|
{
|
|
667
675
|
title: "Get Action Runtime Fact Metadata",
|
|
668
676
|
annotations: { readOnlyHint: true },
|
|
669
|
-
description: "Retrieve runtime fact requirements per Action type. For each Action, shows which input facts must be present in the execution payload \u2014 e.g. MUTATE_FACT always requires its targetVar fact, plus refVar when one is specified. The factRequired flag describes the FACT, not the parameter: refVar is an optional parameter, but if you specify it the named fact must exist. A required fact absent at runtime throws \u2014 the engine never defaults to 0.
|
|
677
|
+
description: "Retrieve runtime fact requirements per Action type. For each Action, shows which input facts must be present in the execution payload \u2014 e.g. MUTATE_FACT always requires its targetVar fact, plus refVar when one is specified. The factRequired flag describes the FACT, not the parameter: refVar is an optional parameter, but if you specify it the named fact must exist. A required fact absent at runtime throws \u2014 the engine never defaults to 0. These facts must be sent in the request (P-015 otherwise), even when an earlier action in the same rule writes them. SET_FACT requires no input fact: it is the only action that can write a key the request did not send, and its targetVar must be a registered fact (ACT-032). Static data, safe to cache in-session.",
|
|
670
678
|
inputSchema: z5.object({})
|
|
671
679
|
},
|
|
672
680
|
async () => callApi("GET", "schema/action-metadata")
|
|
@@ -676,7 +684,7 @@ function registerFactTools(server, callApi) {
|
|
|
676
684
|
{
|
|
677
685
|
title: "List Unregistered Facts",
|
|
678
686
|
annotations: { readOnlyHint: true },
|
|
679
|
-
description: "List facts referenced by a version's rules but not yet defined (read-only
|
|
687
|
+
description: "List facts referenced by a version's rules but not yet defined (read-only). Keys that rules only read do not block publish/deploy; a rule whose action targetVar is not a registered fact is rejected at save and publish with ACT-032. Version-wide: covers every rule in the version. Each entry carries the inferred type, suggested name, and where it is referenced (condition/action). Register them with lexq_facts_create to enable type validation and the dry-run requirements analyzer.",
|
|
680
688
|
inputSchema: z5.object({
|
|
681
689
|
groupId: z5.string().uuid().describe("Policy group ID"),
|
|
682
690
|
versionId: z5.string().uuid().describe("Version ID")
|
|
@@ -709,7 +717,7 @@ function registerDeployTools(server, callApi) {
|
|
|
709
717
|
{
|
|
710
718
|
title: "Publish Version",
|
|
711
719
|
annotations: { readOnlyHint: false, destructiveHint: false },
|
|
712
|
-
description: `Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts
|
|
720
|
+
description: `Publish a DRAFT version (DRAFT \u2192 ACTIVE). Locks the version from further edits. Must have at least one rule. Undefined facts that rules only read do not block publishing; call lexq_facts_unregistered first to review them. Publishing fails if an action's targetVar is not a registered fact (ACT-032), if the version's compiled rules exceed ${MAX_SNAPSHOT_BYTES / 1024} KB, or if its effective end has already passed (P-058); move the end into the future with lexq_versions_update first.`,
|
|
713
721
|
inputSchema: z6.object({
|
|
714
722
|
groupId: z6.string().uuid().describe("Policy group ID"),
|
|
715
723
|
versionId: z6.string().uuid().describe("Version ID to publish"),
|
package/package.json
CHANGED
|
@@ -480,8 +480,10 @@ lexq analytics dry-run --version-id <vid> --debug --json '{
|
|
|
480
480
|
|
|
481
481
|
**Notes**
|
|
482
482
|
|
|
483
|
-
- `SET_FACT`
|
|
484
|
-
|
|
483
|
+
- Register a `SET_FACT` target before saving the rule, as the step above does. A rule whose
|
|
484
|
+
`targetVar` is not a registered fact is rejected with `ACT-032`.
|
|
485
|
+
- At execution, `SET_FACT` writes the key even when the request did not send it. `MUTATE_FACT`
|
|
486
|
+
requires the request to send its target. That is the division of labor between them.
|
|
485
487
|
- Flags appear in `generatedVariables` in the response. `SET_FACT` produces no `__delta` because
|
|
486
488
|
it is an assignment, not an arithmetic change.
|
|
487
489
|
- Segment on a `LIST_STRING` fact with `HAS_ANY` / `HAS_ALL` / `HAS_NONE`, not `CONTAINS`.
|
|
@@ -181,14 +181,14 @@ Each rule can have multiple actions. Actions fire sequentially.
|
|
|
181
181
|
| Type | Description | Key Parameters |
|
|
182
182
|
|---------------|--------------------------------------------|----------------------------------------------------------------------|
|
|
183
183
|
| `MUTATE_FACT` | Arithmetic change to a numeric fact | `targetVar`, `operator`, `method`, `operand`, `refVar?`, `rounding?` |
|
|
184
|
-
| `SET_FACT` | Assign a literal value
|
|
184
|
+
| `SET_FACT` | Assign a literal value to a registered fact | `targetVar`, `value` |
|
|
185
185
|
| `BLOCK` | Record a rejection decision | `reason` |
|
|
186
186
|
|
|
187
187
|
### `MUTATE_FACT` parameters
|
|
188
188
|
|
|
189
189
|
| Parameter | Required | Meaning |
|
|
190
190
|
|-------------|----------|-------------------------------------------------------------------------------|
|
|
191
|
-
| `targetVar` | always | The fact this action **reads and writes**. Must
|
|
191
|
+
| `targetVar` | always | The fact this action **reads and writes**. Must be registered and present as a number at execution. |
|
|
192
192
|
| `operator` | always | `ASSIGN` \| `ADD` \| `SUB` \| `MUL` \| `DIV` |
|
|
193
193
|
| `method` | always | `PERCENTAGE` \| `AMOUNT` — dictates the unit of `operand` |
|
|
194
194
|
| `operand` | always | The arithmetic operand. Percent when PERCENTAGE, absolute amount when AMOUNT. |
|
|
@@ -235,8 +235,15 @@ Use `refVar` when the base differs from the target:
|
|
|
235
235
|
|
|
236
236
|
### `SET_FACT` vs `MUTATE_FACT`
|
|
237
237
|
|
|
238
|
-
|
|
239
|
-
|
|
238
|
+
Both actions write to `targetVar`, and it must be a **registered fact**. Saving or publishing a
|
|
239
|
+
rule whose `targetVar` is not registered fails with `ACT-032`; register it with
|
|
240
|
+
`lexq facts create` first. Keys a rule only reads (condition fields, `refVar`) may stay
|
|
241
|
+
unregistered.
|
|
242
|
+
|
|
243
|
+
At execution, they differ in what the request must send. `SET_FACT` writes the value even when
|
|
244
|
+
the request did not send the key. `MUTATE_FACT` requires the request to send the target (`P-015`
|
|
245
|
+
otherwise), and the target's value must be a number when the action runs. "Write something the
|
|
246
|
+
request didn't send" is `SET_FACT`'s job.
|
|
240
247
|
|
|
241
248
|
### `BLOCK` does not halt execution
|
|
242
249
|
|