@thinkingai/ae-cli 6.0.48 → 6.1.0-project-role-upsert.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.
Files changed (82) hide show
  1. package/README.md +4 -1
  2. package/README.zh.md +4 -1
  3. package/dist/{capability-J4FU4JZW.js → capability-AXFQW5WM.js} +13 -10
  4. package/dist/{chunk-6KBBAPPP.js → chunk-JDPEVVHR.js} +4 -3
  5. package/dist/index.js +23 -13
  6. package/dist/{metadata-3J5ZAVMF.js → metadata-SOALPEA7.js} +3 -3
  7. package/dist/{personal-semantic-preference-32AAJ37M.js → personal-semantic-preference-LOF33N5X.js} +2 -2
  8. package/dist/project-semantic-RV6NA5LN.js +1113 -0
  9. package/dist/{te-analysis-WHYXHRJD.js → te-analysis-TV2YZ4IC.js} +23 -7
  10. package/dist/{te-engage-DHKNJ5BO.js → te-engage-EUVMTUDJ.js} +63 -5
  11. package/dist/te-experiment-ESEYE2SK.js +1059 -0
  12. package/package.json +2 -1
  13. package/skills/ae-analysis/SKILL.md +17 -1
  14. package/skills/ae-analysis/references/command_index.md +1 -1
  15. package/skills/ae-analysis/references/personal_semantic_preference_add.md +1 -1
  16. package/skills/ae-analysis/references/personal_semantic_preference_get.md +3 -1
  17. package/skills/ae-analysis/references/personal_semantic_preference_list.md +3 -1
  18. package/skills/ae-analysis/references/personal_semantic_preference_update.md +1 -1
  19. package/skills/ae-analysis/references/project_role_upsert.md +32 -2
  20. package/skills/ae-engage/SKILL.md +2 -0
  21. package/skills/ae-engage/references/save-flow.md +37 -1
  22. package/skills/ae-experiment/SKILL.md +117 -0
  23. package/skills/ae-experiment/references/batch_delete_experiment.md +11 -0
  24. package/skills/ae-experiment/references/batch_delete_feature.md +11 -0
  25. package/skills/ae-experiment/references/batch_delete_traffic_layer.md +11 -0
  26. package/skills/ae-experiment/references/cancel_experiment_query_by_request_id.md +11 -0
  27. package/skills/ae-experiment/references/check_experiment_ready.md +17 -0
  28. package/skills/ae-experiment/references/check_experiment_traffic_layer_conflict.md +37 -0
  29. package/skills/ae-experiment/references/delete_metric.md +13 -0
  30. package/skills/ae-experiment/references/manage_experiment.md +17 -0
  31. package/skills/ae-experiment/references/manage_feature_status.md +11 -0
  32. package/skills/ae-experiment/references/manage_feature_whitelist.md +66 -0
  33. package/skills/ae-experiment/references/manage_guardrail_metrics.md +26 -0
  34. package/skills/ae-experiment/references/query_bucket_list.md +12 -0
  35. package/skills/ae-experiment/references/query_experiment_detail.md +19 -0
  36. package/skills/ae-experiment/references/query_experiment_list.md +22 -0
  37. package/skills/ae-experiment/references/query_experiment_list_archived.md +18 -0
  38. package/skills/ae-experiment/references/query_experiment_metric_trend.md +12 -0
  39. package/skills/ae-experiment/references/query_experiment_operation_log.md +17 -0
  40. package/skills/ae-experiment/references/query_experiment_report_summary.md +12 -0
  41. package/skills/ae-experiment/references/query_experiment_sample_size_report.md +13 -0
  42. package/skills/ae-experiment/references/query_feature_detail.md +14 -0
  43. package/skills/ae-experiment/references/query_feature_list.md +12 -0
  44. package/skills/ae-experiment/references/query_feature_operation_log.md +19 -0
  45. package/skills/ae-experiment/references/query_feature_version_list.md +20 -0
  46. package/skills/ae-experiment/references/query_metric_detail.md +18 -0
  47. package/skills/ae-experiment/references/query_metric_list.md +15 -0
  48. package/skills/ae-experiment/references/query_traffic_layer_detail.md +13 -0
  49. package/skills/ae-experiment/references/query_traffic_layer_list.md +12 -0
  50. package/skills/ae-experiment/references/save_build_guide.md +39 -0
  51. package/skills/ae-experiment/references/save_experiment.md +210 -0
  52. package/skills/ae-experiment/references/save_feature.md +13 -0
  53. package/skills/ae-experiment/references/save_metric.md +91 -0
  54. package/skills/ae-experiment/references/save_submit_experiment.md +16 -0
  55. package/skills/ae-experiment/references/save_traffic_layer.md +13 -0
  56. package/skills/ae-experiment/references/save_validate.md +33 -0
  57. package/skills/ae-experiment/references/update_experiment_group.md +20 -0
  58. package/skills/ae-experiment-design/SKILL.md +149 -0
  59. package/skills/ae-experiment-design/agents/openai.yaml +4 -0
  60. package/skills/ae-experiment-design/references/client-experiment-sdk.md +147 -0
  61. package/skills/ae-experiment-design/references/experiment-creation.md +108 -0
  62. package/skills/ae-experiment-design/references/experiment-sdk-contract.md +100 -0
  63. package/skills/ae-experiment-design/references/exposure-contract.md +91 -0
  64. package/skills/ae-experiment-design/references/hybrid-experiment-sdk.md +74 -0
  65. package/skills/ae-experiment-design/references/metric-readiness.md +143 -0
  66. package/skills/ae-experiment-design/references/platform-operations.md +105 -0
  67. package/skills/ae-experiment-design/references/sdk-index.md +76 -0
  68. package/skills/ae-experiment-design/references/sdk-integration.md +114 -0
  69. package/skills/ae-experiment-design/references/sdk-troubleshooting.md +139 -0
  70. package/skills/ae-experiment-design/references/server-experiment-sdk.md +78 -0
  71. package/skills/ae-experiment-design/scripts/calculate_experiment_plan.py +450 -0
  72. package/skills/ae-experiment-insight/SKILL.md +149 -0
  73. package/skills/ae-experiment-insight/agents/openai.yaml +4 -0
  74. package/skills/ae-experiment-insight/references/decision-framework.md +69 -0
  75. package/skills/ae-experiment-insight/references/diagnostic-playbook.md +225 -0
  76. package/skills/ae-experiment-insight/references/platform-operations.md +82 -0
  77. package/skills/ae-experiment-insight/scripts/analyze_experiment.py +478 -0
  78. package/skills/ae-project-semantic/SKILL.md +193 -0
  79. package/skills/ae-project-semantic/references/query-routing-v5.md +165 -0
  80. package/skills/ae-project-semantic/references/recommendation-quality.md +68 -0
  81. package/dist/{chunk-HPLNYQPM.js → chunk-RSG4ONOI.js} +3 -3
  82. package/dist/{sync-2GTAKZYX.js → sync-YV3E66IF.js} +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thinkingai/ae-cli",
3
- "version": "6.0.48",
3
+ "version": "6.1.0-project-role-upsert.1",
4
4
  "description": "CLI tool for ThinkingAI (AE) analytics platform",
5
5
  "type": "module",
6
6
  "bin": {
@@ -38,6 +38,7 @@
38
38
  "verify:retired-analysis-commands": "node --test test/retired-analysis-commands.test.mjs",
39
39
  "verify:retired-api-command": "node --test test/retired-api-command.test.mjs",
40
40
  "verify:analysis-common-tools": "node scripts/verify-te-common-tools.mjs",
41
+ "verify:experiment-tools": "node scripts/verify-te-experiment-tools.mjs && node --import tsx test/experiment/experiment-capability-command.test.mjs",
41
42
  "verify:team-tools": "node scripts/verify-te-team-tools.mjs",
42
43
  "verify:agent-tools": "node --test test/agent-command-registry.test.mjs && tsx tests/te-agent-credentials.test.ts && tsx tests/te-agent-unified-auth.test.ts && tsx tests/te-agent-conversations.test.ts && tsx tests/te-agent-automations.test.ts && tsx scripts/verify-agent-tools.mjs && npm run verify:approval && npm run verify:agent-distribution && npm run verify:agent-context && npm run verify:sandbox-tools",
43
44
  "verify:agent-context": "tsx tests/agent-context-command.test.ts",
@@ -108,12 +108,24 @@ Before a project-scoped command:
108
108
  3. If there are multiple plausible projects, the host is unclear, or no project matches, show the candidates and ask; never guess.
109
109
  4. Re-verify after the user changes project, host, or environment.
110
110
 
111
+ ### Project Semantics
112
+
113
+ Before answering project-scoped analysis or asset-governance requests, call `ae-cli project-semantic list --project-id <project_id>` once after the project is resolved. This is the governed project semantic catalog. The list is already filtered to active, fresh project semantics and sorted by heat, so do not page or search the database yourself.
114
+
115
+ If one project semantic is actually adopted to interpret the user's wording, asset selection, metric definition, calculation convention, or project-wide business rule, fetch it with `ae-cli project-semantic get --project-id <project_id> --id <semantic_id> --mark-used`. Do not pass `--mark-used` for project semantics that were only inspected or rejected.
116
+
117
+ For project semantic recommendation, switch to the `ae-project-semantic` skill. This skill only consumes published project semantics during analysis tasks.
118
+
119
+ Published project semantics are the formal project-wide authority. A current-turn user instruction may request a different analysis, but the result must be labeled as an explicit non-formal deviation rather than silently replacing the published definition.
120
+
111
121
  ### Personal Semantic Preferences
112
122
 
113
123
  Before answering project-scoped analysis or asset-governance requests, call `ae-cli personal-semantic-preference list --project-id <project_id>` once per host, authenticated user, project, and conversation after the project is resolved. Keep that lightweight directory in conversation context; do not page it, search the database, or call list again for each question. The backend returns at most 200 entries using `HOT_160_PLUS_RECENT_40` and may return fewer to keep the payload within its size limit.
114
124
 
115
125
  Use the returned compact catalog only as context. If one item is actually adopted to interpret the user's wording, asset selection, metric preference, or output style, fetch it with `ae-cli personal-semantic-preference get --project-id <project_id> --id <preference_id> --mark-used`. This also applies when the matched item is being used as the target for an `update`. Do not pass `--mark-used` for items that were only inspected or rejected.
116
126
 
127
+ Apply the two catalogs by authority and purpose, not as one flat ranking. Published project semantics define the formal business meaning. Personal semantics supply the current user's defaults, interpretation corrections, asset choices, and output preferences where they do not conflict. If a personal semantic conflicts with a published project semantic, use the project semantic for the formal result and explicitly disclose the difference; never silently overwrite the personal record. If the user explicitly requests the personal alternative for the current task, execute it as a labeled non-formal variation.
128
+
117
129
  The Agent owns the personal preference capture trigger. Choose `context_type` by meaning:
118
130
 
119
131
  - `preference`: durable interpretation or output preference without an exact asset binding.
@@ -121,12 +133,16 @@ The Agent owns the personal preference capture trigger. Choose `context_type` by
121
133
  - `experience`: a confirmed reusable work method without an exact asset binding.
122
134
  - `background`: stable personal context without an exact asset binding.
123
135
 
124
- Any stable choice of a concrete asset, including an event-selection scenario, must use `asset_context`; do not encode asset IDs only in prose. A current-user working definition remains eligible for personal storage even when it would also benefit other users. Store it only as the current user's preference; do not copy the bound asset definition into its content or imply that it is shared authority. Keep future governance or lifecycle instructions out of the stored content. Do not save transient task details, one-off analysis results, company knowledge, or standalone metadata facts.
136
+ Any stable choice of a concrete asset, including an event-selection scenario, must use `asset_context`; do not encode asset IDs only in prose. During a project task, collect durable current-user preferences, stable interpretation corrections, reusable asset-selection choices, recurring output preferences, and current-user working definitions that have not become approved project semantics. A working definition remains eligible for personal storage even when it would also benefit other project users. Store it only as the current user's preference; never describe it as approved project authority or copy a bound asset definition into its content. Keep future governance or lifecycle instructions out of the stored content. Do not save transient task details, one-off analysis results, company knowledge, standalone metadata facts, reports, or dashboards as personal preferences.
125
137
 
126
138
  An explicit stable statement, correction, or confirmation that passes that evidence gate authorizes `personal-semantic-preference add` or `update` without a second "save" confirmation. Compare against the already loaded catalog first; when one existing preference matches, fetch it with `--mark-used`, update that existing preference, and avoid creating a duplicate. Otherwise add a new one. An explicit instruction not to retain it always wins. Delete remains high risk and requires explicit user confirmation.
127
139
 
140
+ Personal capture and project recommendation are independent. Save or update the personal semantic first when its evidence gate is met. If the same content looks reusable as a formal project-wide definition, finish the current task and then ask whether the user wants to recommend it as a project semantic candidate. Do not make project recommendation a prerequisite for personal capture, do not submit a candidate without that user choice, and never approve or publish on behalf of an ordinary user.
141
+
128
142
  After a successful add, update, or delete, merge that response into the conversation's cached directory locally. Do not call list again merely to observe the write.
129
143
 
144
+ When a later published project semantic matches a personal semantic, treat the project semantic as formal and allow the personal record to become redundant, expire, or merge through the supported lifecycle. When they conflict, keep the project semantic formal, disclose the conflict, and preserve the personal record unless the user explicitly changes or deletes it. These are consumption and lifecycle rules; do not append them to the stored personal semantic content.
145
+
130
146
  Stale or expired preferences are automatically hidden by list filtering and backend maintenance. Do not look for or invent a separate command for that behavior.
131
147
 
132
148
  ### C. FUZZY_SEARCH_FALLBACK
@@ -248,7 +248,7 @@ This is the exhaustive command and flag inventory for the analysis skill. Read t
248
248
  | `ae-cli project role delete` | project.role.delete | high-risk-write | `--project-id` (number; required) — Numeric project ID.<br>`--role-name` (string; required) — Role name to delete.<br>`--new-role-name` (string; optional) — Role name to migrate users to before deletion. | [project_role_delete.md](project_role_delete.md) |
249
249
  | `ae-cli project role get` | project.role.get | read | `--project-id` (number; required) — Numeric project ID.<br>`--role-name` (string; required) — Role name. | [project_role_get.md](project_role_get.md) |
250
250
  | `ae-cli project role list` | project.role.list | read | `--company-id` (number; optional) — Company ID. Required when project_id is absent.<br>`--project-id` (number; required) — Numeric project ID.<br>`--visible-only` (boolean; optional) — When true, list roles visible to the current user. | [project_role_list.md](project_role_list.md) |
251
- | `ae-cli project role upsert` | project.role.upsert | write | `--project-id` (number; required) — Numeric project ID.<br>`--payload` (json; required) — Required snake_case capability payload. Read the dedicated command reference for its semantic shape; an empty object is not a generic valid payload. | [project_role_upsert.md](project_role_upsert.md) |
251
+ | `ae-cli project role upsert` | project.role.upsert | write | `--project-id` (number; required) — Numeric project ID.<br>`--payload` (json; required) — Role payload with role_func_list object items containing function_name and has_power (0 or 1). | [project_role_upsert.md](project_role_upsert.md) |
252
252
  | `ae-cli project role-function list` | project.role_function.list | read | `--company-id` (number; optional) — Company ID.<br>`--project-id` (number; required) — Numeric project ID.<br>`--role-name` (string; optional) — Single role name.<br>`--role-names` (json; optional) — Role names JSON array. When omitted, all role functions are returned.<br>`--show-system-func` (boolean; optional) — Whether to include system functions. Default false. | [project_role_function_list.md](project_role_function_list.md) |
253
253
  | `ae-cli project role-user list` | project.role_user.list | read | `--project-id` (number; required) — Numeric project ID.<br>`--role-name` (string; required) — Role name. | [project_role_user_list.md](project_role_user_list.md) |
254
254
  | `ae-cli project timezone get` | project.timezone.get | read | `--project-id` (number; required) — Numeric project ID. | [project_timezone_get.md](project_timezone_get.md) |
@@ -16,7 +16,7 @@ Use `preference` for durable interpretation/output preferences, `asset_context`
16
16
 
17
17
  `--request-id` is an idempotency key; omit it for ordinary interactive use and the CLI will generate one.
18
18
 
19
- This command creates only a current-user preference. Do not reject an otherwise valid personal preference merely because the same content may benefit other users, and do not imply that the saved preference is shared authority.
19
+ This command creates only a current-user preference; it never creates or approves a project semantic. Do not reject an otherwise valid personal preference merely because the same content may benefit other users, and do not imply that the saved preference is shared authority. Keep project-candidate recommendation separate: after personal capture, ask whether to recommend broadly reusable content as a project semantic candidate, and submit nothing without that choice.
20
20
 
21
21
  Store only the present working preference. Do not append future governance or lifecycle instructions. Do not use this command for company knowledge, standalone metadata facts, reports, dashboards, transient task details, one-off analysis results, or automatic stale/expired preference handling.
22
22
 
@@ -12,6 +12,8 @@ ae-cli personal-semantic-preference get --project-id <project_id> --id <preferen
12
12
 
13
13
  Input uses `project_id`, `id`, and optional `mark_used`. `id` must be the exact `preference_<id>` value returned by list/add.
14
14
 
15
- Do not use this command as a keyword search or asset catalog lookup. Do not call it repeatedly for every catalog row. Do not use `--mark-used` for a candidate that turns out not to match the user's intent or is only inspected and then rejected.
15
+ Do not use this command as a keyword search, project semantics lookup, or asset catalog lookup. Do not call it repeatedly for every catalog row. Do not use `--mark-used` for a candidate that turns out not to match the user's intent or is only inspected and then rejected.
16
+
17
+ When a published project semantic conflicts with the personal item, the project semantic is the formal definition. Fetch and mark the personal item only when it materially affects the response, such as an explicitly requested non-formal alternative; never silently use it to override the project semantic.
16
18
 
17
19
  Output is the gateway envelope. `data.preference` contains the full personal preference, including content, complete ordered `resource_refs`, and revision. When `--mark-used` is set, the backend increments `heat_count` and updates `last_used_at` for that record.
@@ -12,8 +12,10 @@ ae-cli personal-semantic-preference list --project-id <project_id>
12
12
 
13
13
  Input uses `project_id` only. Do not add pagination parameters: the backend returns a compact catalog intended for agent context.
14
14
 
15
- Do not use this command for shared knowledge, metadata catalogs, report/dashboard lists, or complete asset discovery. It only returns the current user's personal semantic preferences in the current project.
15
+ Do not use this command for project semantics, shared knowledge, metadata catalogs, report/dashboard lists, or complete asset discovery. It only returns the current user's personal semantic preferences in the current project.
16
16
 
17
17
  Output is the gateway envelope. `data.items[]` contains only `id`, `context_type`, `title`, truncated `summary`, limited `keywords`, `resource_ref_count`, distinct `resource_types`, and `revision`; it deliberately omits content, full asset references, heat, and timestamps. `data.returned_count` is at most 200, `data.truncated` says whether entries were omitted, and `data.selection_policy` is `HOT_160_PLUS_RECENT_40`: up to 160 highest-heat items plus up to 40 recently changed items not already selected. The backend may return fewer items to keep the data payload within 64 KiB.
18
18
 
19
19
  If one returned item is actually adopted to interpret the user's request, call `ae-cli personal-semantic-preference get --project-id <project_id> --id <preference_id> --mark-used` before using its full content. Do not mark an item used when it was only inspected or rejected.
20
+
21
+ Compare a likely match with the published project semantic catalog. Published project semantics remain the formal project-wide authority; personal items provide current-user defaults and working interpretations. If they conflict, use the project semantic for the formal result, explicitly disclose the personal difference, and do not mark the personal item used unless the user explicitly adopts it as a labeled alternative.
@@ -12,7 +12,7 @@ ae-cli personal-semantic-preference update --project-id <project_id> --id <prefe
12
12
 
13
13
  The update replaces all editable fields. Include the full intended `title`, `summary`, `content`, keywords, and asset bindings rather than a partial patch. `asset_context` requires 1 to 50 complete ordered `resource_refs`; other context types cannot contain non-empty refs.
14
14
 
15
- This command updates only the current-user preference. Do not block the update merely because the same content may benefit other users, and do not imply that the saved preference is shared authority.
15
+ This command updates only the current-user preference; it does not update, approve, or publish project semantics. Do not block the update merely because the same content may benefit other users, and do not imply that the saved preference is shared authority. Keep project-candidate recommendation separate and ask before submitting it.
16
16
 
17
17
  Keep future governance and lifecycle handling out of the stored content. Do not use this command for shared knowledge, standalone metadata facts, reports, dashboards, transient task details, one-off analysis results, or automatic stale/expired preference handling.
18
18
 
@@ -8,12 +8,42 @@ Command:
8
8
 
9
9
  ```bash
10
10
  ae-cli project role upsert --project-id <project_id> --payload <payload>
11
+ ae-cli project role upsert --validate --project-id <project_id> --payload <payload>
11
12
  ae-cli project role upsert --dry-run --project-id <project_id> --payload <payload>
12
13
  ```
13
14
 
14
15
  Capability id: `project.role.upsert`.
15
16
 
16
- Input sends `project_id`, `payload`. Payload keys, JSON arrays, and projection fields must follow the common-service snake_case input schema.
17
+ Input sends `project_id`, `payload`. Payload keys must use snake_case.
18
+
19
+ ## Payload contract
20
+
21
+ `role_func_list` is required and must be a non-empty array of objects. Every item requires:
22
+
23
+ - `function_name`: non-empty string. Resolve valid values with `ae-cli project function list` instead of guessing IDs or sending numeric function IDs.
24
+ - `has_power`: integer `0` or `1` only. Use `1` to select the function and `0` to leave it unselected.
25
+
26
+ For role creation, omit `role_name` and provide `role_desc` with 1 to 80 characters. For an update, provide the existing `role_name`; `role_desc` may remain omitted for compatibility.
27
+
28
+ Functions omitted from `role_func_list` are completed by the service with their permission metadata and `has_power=0`. Do not attempt to replace an object item with a number or string.
29
+
30
+ Create example:
31
+
32
+ ```bash
33
+ ae-cli project role upsert \
34
+ --project-id 196 \
35
+ --payload '{"role_desc":"Data analyst","role_func_list":[{"function_name":"viewReport","has_power":1}]}'
36
+ ```
37
+
38
+ Update example:
39
+
40
+ ```bash
41
+ ae-cli project role upsert \
42
+ --project-id 196 \
43
+ --payload '{"role_name":"custom_role","role_func_list":[{"function_name":"viewReport","has_power":1}]}'
44
+ ```
45
+
46
+ Run with `--validate` first when constructing the payload dynamically. Invalid item types, missing fields, an empty list, or a `has_power` value outside `0` and `1` return a validation error before the role is saved.
17
47
 
18
48
  Output uses the gateway envelope: success is `ok=true,data,meta`; failure is `ok=false,error`. Preserve `request_id` and `invocation_id` when present.
19
49
 
@@ -21,4 +51,4 @@ Output uses the gateway envelope: success is `ok=true,data,meta`; failure is `ok
21
51
  | Parameter | Required | Description |
22
52
  |---|---|---|
23
53
  | `--project-id` | Yes | Numeric project ID. |
24
- | `--payload` | Yes | Role save payload matching RoleSaveRequestDTO in snake_case. |
54
+ | `--payload` | Yes | Role payload with a non-empty `role_func_list` object array; each item contains `function_name` and `has_power` (`0` or `1`). |
@@ -398,6 +398,8 @@ When the user wants to "create a flow / generate a flow canvas / save a flow", d
398
398
  3. Build condition-related nodes with semantic `targetDefinitionRequest` and
399
399
  `triggerDefinition` objects. Resolve real event and property names through Analysis metadata;
400
400
  do not create an intermediate cluster merely to obtain persisted QP.
401
+ For `ab_split_flow` indicators, use `indicatorsDef[].eventDefinition`; always provide the
402
+ aggregate `operator`/`value` and every event-property filter's `operator`/`values`.
401
403
 
402
404
  4. Before building touchpoint nodes such as `message_push`, `wechat_push`, or `webhook_push`, you must call:
403
405
 
@@ -305,9 +305,45 @@ Fallback branch keeps only `branchId` + `branchType: 2`.
305
305
  #### `ab_split_flow`
306
306
 
307
307
  ```json
308
- { "branchList": [ { "branchId": "<branchId>", "branchName": "Control Group", "branchType": 1, "order": 1, "percentageInExperiment": 34 }, { "branchId": "<branchId>", "branchName": "Experiment Group A", "branchType": 2, "order": 2, "percentageInExperiment": 33 } ], "indicatorsDef": [], "activateIndicatorsDef": null }
308
+ {
309
+ "branchList": [
310
+ { "branchId": "control", "branchName": "Control Group", "branchType": 1, "order": 1, "percentageInExperiment": 50 },
311
+ { "branchId": "experiment_a", "branchName": "Experiment Group A", "branchType": 2, "order": 2, "percentageInExperiment": 50 }
312
+ ],
313
+ "indicatorsDef": [
314
+ {
315
+ "indicatorsUuid": "metric_1",
316
+ "name": "Maximum payment amount",
317
+ "desc": "",
318
+ "completionIndicatorType": 0,
319
+ "touch_cycle_num": 1,
320
+ "touch_cycle_num_unit": "day",
321
+ "eventDefinition": {
322
+ "type": "event",
323
+ "event": "payment",
324
+ "aggregation": "max",
325
+ "property": "pay_amount",
326
+ "operator": "gt",
327
+ "value": 0,
328
+ "filters": {
329
+ "relation": "and",
330
+ "items": [
331
+ { "field": "gold", "operator": "gt", "values": [20] }
332
+ ]
333
+ }
334
+ }
335
+ }
336
+ ],
337
+ "activateIndicatorsDef": null
338
+ }
309
339
  ```
310
340
 
341
+ Use `eventDefinition` for new Capability requests. Its top-level `operator` compares the aggregate
342
+ result with `value`; each `filters.items[].operator` compares an event property with its `values`.
343
+ Both comparison levels are explicit and must not be omitted. Do not construct persisted fields such
344
+ as `event`, `taPropQuota`, `uceCalcuSymbol`, `num`, `filts`, or `calcuSymbol`; Hermes compiles them.
345
+ Legacy `event` remains accepted temporarily for older clients, but never send both fields.
346
+
311
347
  #### `event_judge`
312
348
 
313
349
  ```json
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: ae-experiment
3
+ version: 1.0.1
4
+ description: "Use when managing Atlas AB experiments, traffic layers, Features, metrics, buckets, and experiment reports through ae-cli"
5
+ ---
6
+
7
+ # ae-experiment
8
+
9
+ AE CLI (`ae-cli`) exposes Atlas AB Experiment capabilities through the `experiment` domain.
10
+
11
+ ## Global Rules
12
+
13
+ - Prefer `ae-cli experiment <command>` for Atlas AB Experiment work.
14
+ - Use `--project-id` / `-p` for project-scoped commands.
15
+ - Use `--req` JSON for complex save, status, and delete DTOs.
16
+ - Do not invent experiment IDs, traffic layer IDs, bucket IDs, Feature keys, metric IDs, or payload field names.
17
+ - Bind only metric IDs returned by `experiment metric list`; create and verify a missing metric before saving the experiment.
18
+ - Read commands can run directly after IDs are verified.
19
+ - Write commands require explicit user intent and normally keep the confirmation prompt. Use `--dry-run` before write calls when composing JSON.
20
+
21
+ Naming and response boundary:
22
+
23
+ - CLI command segments and flags use kebab-case.
24
+ - Outer Capability input and all response keys use snake_case.
25
+ - Nested business DTOs passed through `--req` keep their native camelCase fields.
26
+ - **CRITICAL:** `save build-guide` / `save validate` responses recursively snake_case
27
+ `example_args.req`. Never copy those keys into `--req`. Use camelCase
28
+ (`expName`, `metricId`, …). Authoritative names:
29
+ `ae-cli capability inspect experiment.experiment.save` (or the matching final save id)
30
+ → `input_schema.properties.req`. `save validate` `valid: true` is **not** a final-save
31
+ schema pass — snake_case `req` can still fail on `experiment … save`.
32
+ - Audience QP is semantic at the CLI boundary: write `targeting.definitionRequest`; read
33
+ `targeting.definition_request`. Never generate or submit `targetConfig`.
34
+ - Metric QP is semantic at the CLI boundary: write `metricDefinition`; read
35
+ `metric_definition`. Never generate or submit `metricConfig`, `calcType`, or `Axxx` codes.
36
+ - Event-property comparisons belong in `metricDefinition.filters`, using
37
+ `{relation,items:[{field,operator,values}]}`. Never put comparison fields directly on
38
+ `metricDefinition`, and never submit raw `filts`, `calcuSymbol`, or `ftv` fields.
39
+ - For metric aggregations `sum` / `avg` / `max` / `distinct_count`, `metricDefinition.property`
40
+ is **required** and must be a concrete available event property from Analysis metadata.
41
+ Never create property aggregations without `property` (for example `metric_avg_no_property_*`).
42
+ - Preset event aggregations `total_count` / `user_count` / `active_days` omit `property`.
43
+ - Experiment metric creation does not support `avg_per_user` / `A105`.
44
+ - Resolve event and property names with Analysis metadata before saving semantic definitions.
45
+ - Lists return `data.items` and `data.total`; detail commands return `data.item`.
46
+ - Readiness returns `data.readiness`; reports return `data.report`; save guides return `data.guide`; save dry-run validation returns `data.validation`; writes return `data.result`.
47
+ - Query cancellation returns `data.success`.
48
+
49
+ ## Typical Workflow
50
+
51
+ 1. Discover reusable assets:
52
+ - `experiment bucket list`
53
+ - `experiment traffic-layer list`
54
+ - `experiment feature list`
55
+ - `experiment metric list`
56
+ 2. Create missing assets if needed:
57
+ - `experiment save build-guide --operation-mode save_metric` when save validation fails or req shape is unclear
58
+ - `experiment save validate --operation-mode save_metric --req '{...}'` before retrying a failed save
59
+ - `experiment traffic-layer save`
60
+ - `experiment feature save`
61
+ - `experiment metric save`
62
+ 3. Create or patch the experiment draft with `experiment experiment save`.
63
+ Use `experiment experiment update-metrics` when replacing metric bindings or assigning guardrail roles.
64
+ 4. Check readiness with `experiment experiment ready-check`.
65
+ 5. For a non-mutex traffic layer, run `experiment experiment conflict-check` before submit (needs `feature_key_list` from context or `experiment get`).
66
+ 6. Move status with `experiment experiment manage`.
67
+ 7. Query reports with `experiment report summary`, `experiment report sample-size`, and `experiment report metric-trend`.
68
+
69
+ If an experiment save returns `error_code: METRIC_NOT_FOUND`, list metrics for the same project. Create and verify the metric before retrying; never retry with another invented ID. Metric deletion returns `error_code: METRIC_IN_USE` while an active experiment binding exists.
70
+
71
+ ## Parameter Conventions
72
+
73
+ - Experiment save payloads distinguish two allocation fields: experiment-level `req.allocation` (**integer only; no decimals**) and group-level `req.groups[].allocation` (**integer only; sum must equal `100` exactly**).
74
+ - Public experiment metric roles are `primary`, `secondary`, and `guardrail`. The internal `observation` role is currently unavailable for saves. Guardrail is a binding role; updating metrics replaces the full binding list.
75
+
76
+ ```bash
77
+ ae-cli experiment experiment get --project-id 1 --exp-id exp_123
78
+ ae-cli experiment experiment save --project-id 1 --req '{"expName":"Demo"}' --dry-run
79
+ ae-cli experiment metric save --project-id 1 --req '{"metricId":"payment_gold_sum","metricName":"Payment gold sum","createType":"event","goalDirection":"up","metricDesc":"Gold sum for payments above 10","metricDefinition":{"type":"event","event":"payment","aggregation":"sum","property":"gold","filters":{"relation":"and","items":[{"field":"gold","operator":"gt","values":[10]}]}}}' --dry-run
80
+ ae-cli experiment report metric-trend --project-id 1 --exp-id exp_123 --metric-id metric_1 --start-time 2026-07-01 --end-time 2026-07-07
81
+ ```
82
+
83
+ Optional global parameters work as in other domains: `--host`, `--mcp-url`, `--format`, `--jq`, `--dry-run`, and `--yes`.
84
+
85
+ ## References
86
+
87
+ Open the matching file in `references/` before using a command, especially for write operations and JSON payloads.
88
+
89
+ ### Save Helpers
90
+
91
+ `experiment save build-guide`, `experiment save validate`
92
+
93
+ When a save command returns `next_tool: experiment.save.build-guide`, call the guide first, then `experiment save validate`, then retry the final save capability.
94
+
95
+ Read [`save_build_guide.md`](references/save_build_guide.md) and
96
+ [`save_validate.md`](references/save_validate.md) before using these helpers. Rebuild
97
+ `--req` in camelCase from `inspect` / skill references; do not paste `example_args.req`.
98
+
99
+ ### Experiment
100
+
101
+ `experiment experiment save`, `experiment experiment update-metrics`, `capability run experiment.experiment.save-submit`, `experiment experiment list`, `experiment experiment list-archived`, `experiment experiment get`, `experiment experiment ready-check`, `experiment experiment conflict-check`, `experiment experiment manage`, `experiment experiment update-group`, `experiment experiment batch-delete`, `experiment operation-log query`
102
+
103
+ Read [`manage_guardrail_metrics.md`](references/manage_guardrail_metrics.md) before assigning or replacing metric roles.
104
+
105
+ ### Traffic Layer and Buckets
106
+
107
+ `experiment traffic-layer save`, `experiment traffic-layer get`, `experiment traffic-layer list`, `experiment traffic-layer batch-delete`, `experiment bucket list`
108
+
109
+ ### Reports
110
+
111
+ `experiment report summary`, `experiment report sample-size`, `experiment report metric-trend`, `capability run experiment.query.cancel`
112
+
113
+ ### Metric and Feature
114
+
115
+ `experiment metric save`, `experiment metric get`, `experiment metric list`, `experiment metric delete`, `experiment feature save`, `experiment feature update-status`, `experiment feature get`, `experiment feature list`, `experiment feature version-list`, `experiment feature operation-log query`, `experiment feature batch-delete`, `experiment feature whitelist list`, `experiment feature whitelist save`, `experiment feature whitelist update-status`, `experiment feature whitelist batch-delete`
116
+
117
+ Read [`manage_feature_whitelist.md`](references/manage_feature_whitelist.md) before querying or changing Feature whitelist rules.
@@ -0,0 +1,11 @@
1
+ # experiment experiment batch-delete
2
+
3
+ Batch delete experiments.
4
+
5
+ ```bash
6
+ ae-cli experiment experiment batch-delete --project-id <id> --exp-ids '["exp_1","exp_2"]' [--yes]
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--exp-ids`: Experiment ID list as JSON array.
@@ -0,0 +1,11 @@
1
+ # experiment feature batch-delete
2
+
3
+ Batch delete Features.
4
+
5
+ ```bash
6
+ ae-cli experiment feature batch-delete --project-id <id> --req '<json>' [--yes]
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--req`: Feature delete request JSON object.
@@ -0,0 +1,11 @@
1
+ # experiment traffic-layer batch-delete
2
+
3
+ Batch delete traffic layers.
4
+
5
+ ```bash
6
+ ae-cli experiment traffic-layer batch-delete --project-id <id> --layer-ids '["layer_1","layer_2"]' [--yes]
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--layer-ids`: Traffic layer ID list as JSON array.
@@ -0,0 +1,11 @@
1
+ # capability run experiment.query.cancel
2
+
3
+ Cancel a running experiment report query.
4
+
5
+ ```bash
6
+ ae-cli capability run experiment.query.cancel --input '{"request_id":"<id>"}'
7
+ ```
8
+
9
+ Required input: `request_id`.
10
+
11
+ Response shape: `data.success`.
@@ -0,0 +1,17 @@
1
+ # experiment experiment ready-check
2
+
3
+ Check whether an experiment can enter online status transitions.
4
+
5
+ ```bash
6
+ ae-cli experiment experiment ready-check --project-id <id> --exp-id <expId>
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--exp-id`: Experiment ID.
12
+
13
+ Use this before `experiment experiment manage` moves an experiment to `pending`, `testing`, or `running`.
14
+
15
+ Common `groups` failure: `atlas.service.error.experiment.group.allocation.invalid`. Rule: each `groups[].allocation` must be an **integer**, and **sum = 100 exactly** (for example `34 + 33 + 33 = 100`).
16
+
17
+ Response shape: the readiness result is in `data.readiness`, with recursively snake_case keys.
@@ -0,0 +1,37 @@
1
+ # experiment experiment conflict-check
2
+
3
+ Pre-submit check for cross-layer Feature conflicts on a **non-mutex** traffic layer.
4
+
5
+ Reuse the existing Hermes `trafficLayerConflictCheck` API. Do **not** call this command for mutex traffic layers.
6
+
7
+ ## Workflow
8
+
9
+ 1. Ensure you already have the Feature keys for the current experiment:
10
+ - Editing an existing draft: call `experiment experiment get` and read `feature_key_list`.
11
+ - Creating a new experiment: reuse the Feature keys already chosen in the current workflow.
12
+ 2. Call conflict-check with the selected non-mutex `traffic-layer-id`.
13
+ 3. Interpret the response before `save-submit`:
14
+ - `data.features` non-empty: some Features are not enabled.
15
+ - `data.experiments` non-empty: same Features are active on other traffic layers.
16
+ - both empty: no conflict signal from this check.
17
+
18
+ ```bash
19
+ ae-cli experiment experiment conflict-check \
20
+ --project-id <id> \
21
+ --feature-key-list '["checkout_color"]' \
22
+ --traffic-layer-id <layer-id>
23
+
24
+ ae-cli experiment experiment conflict-check \
25
+ --project-id <id> \
26
+ --feature-key-list '["checkout_color"]' \
27
+ --traffic-layer-id <layer-id> \
28
+ --exp-id <exp-id>
29
+ ```
30
+
31
+ Flags:
32
+ - `--project-id`, `-p`: Project ID.
33
+ - `--feature-key-list`: Required JSON string array of Feature keys selected by the current experiment.
34
+ - `--traffic-layer-id`: Required selected non-mutex traffic layer ID.
35
+ - `--exp-id`: Optional current experiment ID when editing an existing draft (excludes self from conflicts).
36
+
37
+ Response shape: `data.experiments` and `data.features`, with recursively snake_case item keys.
@@ -0,0 +1,13 @@
1
+ # experiment metric delete
2
+
3
+ Delete a metric.
4
+
5
+ ```bash
6
+ ae-cli experiment metric delete --project-id <id> --metric-id <metricId> [--yes]
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--metric-id`: Metric ID.
12
+
13
+ Deletion is rejected with `error_code: METRIC_IN_USE` while the metric has an active experiment binding. Remove the metric from the related experiment before retrying.
@@ -0,0 +1,17 @@
1
+ # experiment experiment manage
2
+
3
+ Manage experiment status.
4
+
5
+ ```bash
6
+ ae-cli experiment experiment manage --project-id <id> --exp-id <expId> --target-status <status> [--remark <text>]
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--exp-id`: Experiment ID.
12
+ - `--target-status`: One of `draft`, `testing`, `pending`, `running`, `paused`, `ended`, `archive`.
13
+ - `--remark`: Optional operation remark.
14
+
15
+ When target status is `pending`, `testing`, or `running`, Hermes performs a ready check before changing status.
16
+
17
+ Response shape: the operation or blocking readiness result is in `data.result`, with object keys recursively converted to snake_case.
@@ -0,0 +1,11 @@
1
+ # experiment feature update-status
2
+
3
+ Update Feature status.
4
+
5
+ ```bash
6
+ ae-cli experiment feature update-status --project-id <id> --req '<json>'
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--req`: Feature status request JSON object.
@@ -0,0 +1,66 @@
1
+ # Feature Whitelist Rules
2
+
3
+ List, create, modify, enable, disable, or delete explicit Feature whitelist rules.
4
+
5
+ ## List
6
+
7
+ ```bash
8
+ ae-cli experiment feature whitelist list \
9
+ --project-id <id> --feature-key <feature_key>
10
+ ```
11
+
12
+ The result contains only explicit whitelist rules for the Feature. Each item exposes `rule_id`,
13
+ `feature_key`, `priority`, `status`, and a structured snake-case `whitelist` array. Use the returned
14
+ `rule_id` for modification, status changes, or deletion.
15
+
16
+ ## Save
17
+
18
+ ```bash
19
+ ae-cli experiment feature whitelist save \
20
+ --project-id <id> \
21
+ --feature-key <feature_key> \
22
+ --status enable \
23
+ --whitelist '[{"bucket_id":"#user_id","rules":[{"ids":["u1","u2"],"value":"on"}]}]'
24
+ ```
25
+
26
+ Pass `--rule-id` to modify an existing whitelist rule. Omit it to create a rule. The Hermes
27
+ Capability fixes the Atlas rule type to `targeting` and serializes the supplied buckets into the
28
+ server's explicit whitelist rule configuration.
29
+
30
+ Rules:
31
+
32
+ - Resolve the Feature with `experiment feature get` before writing.
33
+ - `bucket_id` is the split subject, such as `#user_id` or `#account_id`.
34
+ - Each bucket contains one or more rows with a non-empty `ids` array and a string `value`.
35
+ - An empty string Feature value is allowed. Bucket IDs cannot be empty or duplicated. IDs must be
36
+ unique within one bucket, while different buckets may use the same string ID.
37
+ - The server validates each value against the Feature type and limits the total ID count.
38
+ - Only one explicit whitelist rule can be enabled for the same Feature.
39
+ - Enabling, modifying, disabling, or deleting an enabled whitelist rule immediately creates a new
40
+ version and syncs RCC when the Feature itself is online.
41
+
42
+ ## Status
43
+
44
+ ```bash
45
+ ae-cli experiment feature whitelist update-status \
46
+ --project-id <id> --rule-id <rule_id> --status enable
47
+ ```
48
+
49
+ Valid status transitions exposed by this command are `enable` and `disable`.
50
+
51
+ ## Delete
52
+
53
+ ```bash
54
+ ae-cli experiment feature whitelist batch-delete \
55
+ --project-id <id> --rule-ids '["0001"]'
56
+ ```
57
+
58
+ Deletion is high risk and requires confirmation. Enabled whitelist rules may be deleted; Hermes
59
+ resynchronizes affected online Features afterward.
60
+
61
+ All four commands use Capability Gateway with CLI-token authentication:
62
+
63
+ - `experiment.feature_whitelist.list`
64
+ - `experiment.feature_whitelist.save`
65
+ - `experiment.feature_whitelist.update_status`
66
+ - `experiment.feature_whitelist.batch_delete`
@@ -0,0 +1,26 @@
1
+ # experiment experiment update-metrics
2
+
3
+ Replace the metric bindings of an existing experiment draft and assign metric roles, including
4
+ guardrail metrics.
5
+
6
+ ```bash
7
+ ae-cli experiment experiment update-metrics \
8
+ --project-id <id> \
9
+ --exp-id <exp_id> \
10
+ --metrics '[{"metricId":"conversion","metricRole":"primary"},{"metricId":"error_rate","metricRole":"guardrail"}]'
11
+ ```
12
+
13
+ ## Contract
14
+
15
+ - Discover every `metricId` with `experiment metric list`; never invent metric IDs.
16
+ - `--metrics` must be a non-empty array. Each item requires camelCase `metricId` and `metricRole`.
17
+ - `metricRole` is one of `primary`, `secondary`, or `guardrail`. Do not submit the internal
18
+ `observation` role; Hermes currently rejects it at save boundaries.
19
+ - This command replaces all saved metric bindings because Hermes treats a non-empty `metrics` list
20
+ in a draft patch as a replacement. Include bindings that must remain, not only the new guardrail.
21
+ - Guardrail is a binding role, not a separate metric type. Create the underlying metric first with
22
+ `experiment metric save` when it does not exist.
23
+ - At least one `primary` metric is still required before readiness succeeds.
24
+
25
+ Run with `--dry-run` first, then verify the persisted roles with `experiment experiment get` and
26
+ run `experiment experiment ready-check`.
@@ -0,0 +1,12 @@
1
+ # experiment bucket list
2
+
3
+ Query split buckets in a project.
4
+
5
+ ```bash
6
+ ae-cli experiment bucket list --project-id <id>
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+
12
+ Response shape: `data.items` contains split buckets, `data.total` contains the count, and item keys are recursively snake_case.
@@ -0,0 +1,19 @@
1
+ # experiment experiment get
2
+
3
+ Query full experiment detail.
4
+
5
+ ```bash
6
+ ae-cli experiment experiment get --project-id <id> --exp-id <expId>
7
+ ```
8
+
9
+ Flags:
10
+ - `--project-id`, `-p`: Project ID.
11
+ - `--exp-id`: Experiment ID.
12
+
13
+ Response shape: the experiment is in `data.item`, with recursively snake_case keys such as `exp_id` and `feature_key_list`.
14
+
15
+ When targeting contains reversible QP, it is returned as
16
+ `targeting.definition_request` with `targeting.definition_status=AVAILABLE`.
17
+ An absent definition is `NOT_APPLICABLE`; a historical unsupported definition is
18
+ `UNAVAILABLE` with `definition_unavailable_reason`. The internal `target_config`
19
+ field is never returned.