@dx-do/cli 5.2.48 → 5.2.50

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 (185) hide show
  1. package/README.md +24 -6
  2. package/dist-node/01-discover-vertices.tas-pwngv2fz.md +31 -0
  3. package/dist-node/01-discover-vertices.tas.data-store-svjfrm1f.json5 +29 -0
  4. package/dist-node/01-discover-vertices.tas.data-store-tmd-w650nfzt.json +4 -0
  5. package/dist-node/02-discover-services.tas-867m0m88.md +30 -0
  6. package/dist-node/02-discover-services.tas.data-store-jz0gx5vn.json5 +40 -0
  7. package/dist-node/02-discover-services.tas.data-store-tmd-eq264m6y.json +4 -0
  8. package/dist-node/03-discover-sources.nassql-4tgp9jvv.md +34 -0
  9. package/dist-node/03-discover-sources.nassql.data-store-by6sqk23.json5 +63 -0
  10. package/dist-node/03-discover-sources.nassql.data-store-tmd-n3gy57wm.json +4 -0
  11. package/dist-node/04-discover-metadata-columns.nassql-vhzb0mrq.md +26 -0
  12. package/dist-node/04-discover-metadata-columns.nassql.data-store-c9zr7p0q.json5 +35 -0
  13. package/dist-node/04-discover-metadata-columns.nassql.data-store-tmd-4ygrjvty.json +4 -0
  14. package/dist-node/10-filter-attribute-matches.tas-tafqmtw1.md +33 -0
  15. package/dist-node/10-filter-attribute-matches.tas.data-store-tmd-m2sendv0.json +4 -0
  16. package/dist-node/10-filter-attribute-matches.tas.data-store-whdc6vbc.json5 +35 -0
  17. package/dist-node/11-filter-and-compose.tas-m8856738.md +29 -0
  18. package/dist-node/11-filter-and-compose.tas.data-store-dh5meyk8.json5 +56 -0
  19. package/dist-node/11-filter-and-compose.tas.data-store-tmd-mfn8a16f.json +4 -0
  20. package/dist-node/12-filter-or-not.tas-21zab96s.md +35 -0
  21. package/dist-node/12-filter-or-not.tas.data-store-7vjr4fnd.json5 +83 -0
  22. package/dist-node/12-filter-or-not.tas.data-store-tmd-am9smwe5.json +4 -0
  23. package/dist-node/13-filter-layer.tas-r1ff5anv.md +29 -0
  24. package/dist-node/13-filter-layer.tas.data-store-5mneyz77.json5 +30 -0
  25. package/dist-node/13-filter-layer.tas.data-store-tmd-9qmhyfzr.json +4 -0
  26. package/dist-node/14-filter-traverse.tas-da9jene0.md +38 -0
  27. package/dist-node/14-filter-traverse.tas.data-store-p0vxtfvj.json5 +63 -0
  28. package/dist-node/14-filter-traverse.tas.data-store-tmd-5hepg5wf.json +4 -0
  29. package/dist-node/15-filter-take-vertices-edges.tas-m160qc7z.md +35 -0
  30. package/dist-node/15-filter-take-vertices-edges.tas.data-store-drmcme43.json5 +46 -0
  31. package/dist-node/15-filter-take-vertices-edges.tas.data-store-tmd-8fewsp5s.json +4 -0
  32. package/dist-node/16-filter-projection.tas-dh39mcx8.md +31 -0
  33. package/dist-node/16-filter-projection.tas.data-store-tmd-3r8anggx.json +4 -0
  34. package/dist-node/16-filter-projection.tas.data-store-xjbdry1x.json5 +36 -0
  35. package/dist-node/17-filter-lucene.tas-gyvtzwaa.md +29 -0
  36. package/dist-node/17-filter-lucene.tas.data-store-1knw6srt.json5 +39 -0
  37. package/dist-node/17-filter-lucene.tas.data-store-tmd-5cf3tygg.json +5 -0
  38. package/dist-node/18-filter-variable-reuse.tas-89fq0y6x.md +46 -0
  39. package/dist-node/18-filter-variable-reuse.tas.data-store-by35113t.json5 +55 -0
  40. package/dist-node/18-filter-variable-reuse.tas.data-store-tmd-ak7aprgk.json +4 -0
  41. package/dist-node/19-filter-order-statefilter.tas-hm3z71qj.md +36 -0
  42. package/dist-node/19-filter-order-statefilter.tas.data-store-ra9hj1rz.json5 +51 -0
  43. package/dist-node/19-filter-order-statefilter.tas.data-store-tmd-wqer9xy2.json +4 -0
  44. package/dist-node/20-nassql-from-metadata-basic.nassql-szr2xax1.md +28 -0
  45. package/dist-node/20-nassql-from-metadata-basic.nassql.data-store-tmd-c7drxs1m.json +4 -0
  46. package/dist-node/20-nassql-from-metadata-basic.nassql.data-store-zdf1gp1v.json5 +42 -0
  47. package/dist-node/21-nassql-from-metadata-regex.nassql-78jnsn3e.md +30 -0
  48. package/dist-node/21-nassql-from-metadata-regex.nassql.data-store-ckzsv7h1.json5 +53 -0
  49. package/dist-node/21-nassql-from-metadata-regex.nassql.data-store-tmd-zgr6r9my.json +4 -0
  50. package/dist-node/22-nassql-from-topology.nassql-a71qw9r0.md +42 -0
  51. package/dist-node/22-nassql-from-topology.nassql.data-store-81m23nge.json5 +58 -0
  52. package/dist-node/22-nassql-from-topology.nassql.data-store-tmd-vhpjy6c7.json +4 -0
  53. package/dist-node/23-nassql-join-topology-metadata.nassql-hywxhcg2.md +35 -0
  54. package/dist-node/23-nassql-join-topology-metadata.nassql.data-store-da7q90n2.json5 +76 -0
  55. package/dist-node/23-nassql-join-topology-metadata.nassql.data-store-tmd-rr8wt9qa.json +4 -0
  56. package/dist-node/24-nassql-from-data-window-mean.nassql-q6qsgdxw.md +33 -0
  57. package/dist-node/24-nassql-from-data-window-mean.nassql.data-store-j7xmg7fc.json5 +81 -0
  58. package/dist-node/24-nassql-from-data-window-mean.nassql.data-store-tmd-qgzz2f7v.json +4 -0
  59. package/dist-node/25-nassql-group-order-top.nassql-awgnwn3r.md +30 -0
  60. package/dist-node/25-nassql-group-order-top.nassql.data-store-cmrn300b.json5 +48 -0
  61. package/dist-node/25-nassql-group-order-top.nassql.data-store-tmd-7xpqeh7c.json +4 -0
  62. package/dist-node/26-nassql-filter-predicate.nassql-2t27h5ev.md +41 -0
  63. package/dist-node/26-nassql-filter-predicate.nassql.data-store-k2rgp609.json5 +59 -0
  64. package/dist-node/26-nassql-filter-predicate.nassql.data-store-tmd-m4dddgwm.json +4 -0
  65. package/dist-node/27-nassql-distinct-keep.nassql-6z55dvk3.md +24 -0
  66. package/dist-node/27-nassql-distinct-keep.nassql.data-store-mrx00ys5.json5 +52 -0
  67. package/dist-node/27-nassql-distinct-keep.nassql.data-store-tmd-0p9hy42g.json +4 -0
  68. package/dist-node/28-nassql-format-time.nassql-6wraqgdk.md +30 -0
  69. package/dist-node/28-nassql-format-time.nassql.data-store-tmd-bbbqhz1x.json +4 -0
  70. package/dist-node/28-nassql-format-time.nassql.data-store-tvy8y2cs.json5 +59 -0
  71. package/dist-node/29-nassql-describe-log.nassql-t9vnxeb0.md +31 -0
  72. package/dist-node/29-nassql-describe-log.nassql.data-store-tmd-q4mtczy8.json +4 -0
  73. package/dist-node/29-nassql-describe-log.nassql.data-store-x16y4crx.json5 +51 -0
  74. package/dist-node/30-nassql-map-string.nassql-f2tdknzs.md +30 -0
  75. package/dist-node/30-nassql-map-string.nassql.data-store-t8ahcabn.json5 +53 -0
  76. package/dist-node/30-nassql-map-string.nassql.data-store-tmd-a6xq0bdx.json +4 -0
  77. package/dist-node/31-nassql-join-data-sum.nassql-p16y3xk6.md +26 -0
  78. package/dist-node/31-nassql-join-data-sum.nassql.data-store-dje7wm6v.json5 +64 -0
  79. package/dist-node/31-nassql-join-data-sum.nassql.data-store-tmd-c1pyx1qw.json +4 -0
  80. package/dist-node/32-nassql-bottom-aggregation.nassql-hpgfn77p.md +26 -0
  81. package/dist-node/32-nassql-bottom-aggregation.nassql.data-store-tmd-p0ssj1vc.json +4 -0
  82. package/dist-node/32-nassql-bottom-aggregation.nassql.data-store-v9580caa.json5 +43 -0
  83. package/dist-node/33-nassql-cross-domain-pipeline.nassql-fm0ynphf.md +45 -0
  84. package/dist-node/33-nassql-cross-domain-pipeline.nassql.data-store-tmd-18881drs.json +4 -0
  85. package/dist-node/33-nassql-cross-domain-pipeline.nassql.data-store-vqs9hkx4.json5 +79 -0
  86. package/dist-node/3rdpartylicenses-hx59bakt.txt +885 -0
  87. package/dist-node/50-discover-custom-layers.tas-2hvvpkzw.md +66 -0
  88. package/dist-node/50-discover-custom-layers.tas.data-store-h85zgna9.json5 +36 -0
  89. package/dist-node/50-discover-custom-layers.tas.data-store-tmd-hagn9eak.json +4 -0
  90. package/dist-node/51-collect-counts-everything.tas-nz0ksgdc.md +46 -0
  91. package/dist-node/51-collect-counts-everything.tas.data-store-eypcjah8.json5 +48 -0
  92. package/dist-node/51-collect-counts-everything.tas.data-store-tmd-4pcj94s9.json +4 -0
  93. package/dist-node/52-collect-counts-bulk.tas-eerw4z8s.md +54 -0
  94. package/dist-node/52-collect-counts-bulk.tas.data-store-scedtw1m.json5 +65 -0
  95. package/dist-node/52-collect-counts-bulk.tas.data-store-tmd-csyzj189.json +4 -0
  96. package/dist-node/53-collect-attributes-by-type.tas-cw0285hx.md +71 -0
  97. package/dist-node/53-collect-attributes-by-type.tas.data-store-fvjge4yr.json5 +65 -0
  98. package/dist-node/53-collect-attributes-by-type.tas.data-store-tmd-274qrd8f.json +4 -0
  99. package/dist-node/README-ghxecaz0.md +84 -0
  100. package/dist-node/SKILL-1xn7r9nt.md +104 -0
  101. package/dist-node/agent-25q752kd.md +55 -0
  102. package/dist-node/agent_connection_and_status-0dq7zkpc.md +62 -0
  103. package/dist-node/agent_source_collector-6s06n3rs.md +40 -0
  104. package/dist-node/agentic-mcp-rycd2gh8.md +140 -0
  105. package/dist-node/application-dfva8tz0.md +48 -0
  106. package/dist-node/application-m0q2vaxj.md +74 -0
  107. package/dist-node/attribute_resource_metric_name-pxrceab5.md +56 -0
  108. package/dist-node/browseragent-snippet.template-9megjp8a.html +12 -0
  109. package/dist-node/bulkvertexpatch-1a4qy5vb.md +78 -0
  110. package/dist-node/bundle.pbd-38r15kyd.template +13 -0
  111. package/dist-node/bundle.profile-1wpzpt3d.template +2 -0
  112. package/dist-node/business_transaction-mbqz5ex9.md +61 -0
  113. package/dist-node/chunk-4I3HBO6U-2ebgf7kh.js +127 -0
  114. package/dist-node/chunk-4PMCLJMS-0mqvr4m4.js +1 -0
  115. package/dist-node/chunk-5VSFINOX-ewzpx7wh.js +5 -0
  116. package/dist-node/chunk-72HYG3XZ-kf7hy4vs.js +3625 -0
  117. package/dist-node/chunk-JRM4BLOM-rg32z8w4.js +1 -0
  118. package/dist-node/chunk-Q2JA73UH-akkb8bh3.js +14 -0
  119. package/dist-node/chunk-RNMHSXZF-pdwasrg7.js +1358 -0
  120. package/dist-node/chunk-VV2FJEMA-3rvtkmga.js +321 -0
  121. package/dist-node/chunk-YVD3UK5I-9pxr1jka.js +695 -0
  122. package/dist-node/configuration-1vczsdex.md +104 -0
  123. package/dist-node/dashboards-x0xddksy.md +17 -0
  124. package/dist-node/database_or_inferred-8vqf5gyr.md +75 -0
  125. package/dist-node/default-licensing-config-0p879qpb.template +122 -0
  126. package/dist-node/dependency-3b0neg5x.md +40 -0
  127. package/dist-node/description.md-qwc2bj9r.template +30 -0
  128. package/dist-node/discovery-flow-fw79kbx4.md +116 -0
  129. package/dist-node/dxi_service-13prnpd5.md +59 -0
  130. package/dist-node/entity-relationships-cevz61kj.md +142 -0
  131. package/dist-node/gotchas-8ab64kcd.md +389 -0
  132. package/dist-node/host-es6fxtgx.md +46 -0
  133. package/dist-node/host-j3qqrm5f.md +55 -0
  134. package/dist-node/index-104hyb1m.html +13 -0
  135. package/dist-node/index-7fp2dfas.json +178 -0
  136. package/dist-node/index-g3hh5wez.json +403 -0
  137. package/dist-node/index-mbzg9rhc.json +270 -0
  138. package/dist-node/index-qffdhwgm.json +2479 -0
  139. package/dist-node/inferred-w998vfq1.md +41 -0
  140. package/dist-node/installInstructions.md-k9ghf3dr.template +21 -0
  141. package/dist-node/inventorize-xc9h9bjr.md +34 -0
  142. package/dist-node/investigation-planning-6kcm01h9.md +149 -0
  143. package/dist-node/investigator-flow-jc2s0n46.md +186 -0
  144. package/dist-node/k8s_deployment_and_namespace-69c29152.md +88 -0
  145. package/dist-node/k8s_pod_and_container-9h4v6cmj.md +64 -0
  146. package/dist-node/main-SGLYO5YX-ht69eb0y.js +13 -0
  147. package/dist-node/main.js +397415 -0
  148. package/dist-node/marketplace-srdmzxkj.json +15 -0
  149. package/dist-node/metric-source-names-6cbczyks.md +75 -0
  150. package/dist-node/metrics-grounding-2h4kkbe3.md +130 -0
  151. package/dist-node/mm-cookbook-23jpw721.md +231 -0
  152. package/dist-node/mm-quickstart-x2adfc16.md +106 -0
  153. package/dist-node/nassql-cookbook-n8kc0mff.md +812 -0
  154. package/dist-node/nassql-quickstart-090e0yex.md +149 -0
  155. package/dist-node/plugin-c3bavxvf.json +18 -0
  156. package/dist-node/polyfills-A7ZF72EO-mp884a0b.js +2 -0
  157. package/dist-node/prerendered-routes-523d8gat.json +3 -0
  158. package/dist-node/primeicons-4GST5W3O-jac3wxrf.woff2 +0 -0
  159. package/dist-node/primeicons-DHQU4SEP-760n99pp.svg +345 -0
  160. package/dist-node/primeicons-GEFHGEHP-rc4kaa3b.ttf +0 -0
  161. package/dist-node/primeicons-P53SE5CV-4saz3d5j.woff +0 -0
  162. package/dist-node/primeicons-RSSEDYLY-4d4vbd67.eot +0 -0
  163. package/dist-node/query-vs-analysis-separation-sag1ezcq.md +97 -0
  164. package/dist-node/run-query-vs-run-partial-6138pc94.md +80 -0
  165. package/dist-node/service-5pz5nhzf.md +133 -0
  166. package/dist-node/service-hierarchies-87a4ynpj.md +178 -0
  167. package/dist-node/service-k4f5mkbq.md +51 -0
  168. package/dist-node/servlet_or_frontend-1kjcb7ar.md +76 -0
  169. package/dist-node/src-apm-mfnsq6vw.svg +4 -0
  170. package/dist-node/src-axa-nn28yqmj.svg +4 -0
  171. package/dist-node/src-dxim-fv7ne4qa.svg +4 -0
  172. package/dist-node/styles-23VUPSCU-9ehggc1f.css +1 -0
  173. package/dist-node/tas-cookbook-0y4826rp.md +693 -0
  174. package/dist-node/tas-quickstart-wgcvwffc.md +138 -0
  175. package/dist-node/time-format-0595g01j.md +41 -0
  176. package/dist-node/toggles.pbd-9wscbmng.template +2 -0
  177. package/dist-node/type-host-agbhmn6v.svg +6 -0
  178. package/dist-node/type-metric-p9b90bpx.svg +4 -0
  179. package/dist-node/type-service-k7f1x71k.svg +4 -0
  180. package/dist-node/ui-0b5grqrg.md +113 -0
  181. package/dist-node/universe-b9nhf325.md +47 -0
  182. package/dist-node/universe-fzpwzvxr.md +91 -0
  183. package/dist-node/universes-and-scopes-1cb9pfk7.md +105 -0
  184. package/dist-node/vertex_entity_node-mm3yp9d0.md +31 -0
  185. package/package.json +1 -1
@@ -0,0 +1,138 @@
1
+ ---
2
+ id: tas-quickstart
3
+ title: TAS quickstart — author a topology query
4
+ applies_to: tas
5
+ tags: [getting-started, authoring]
6
+ related: [gotchas, discovery-flow]
7
+ ---
8
+
9
+ # TAS quickstart
10
+
11
+ TAS = topology graph queries. Returns `{ vertices, edges }` shaped by a single
12
+ recursive **filter tree**. Every node is `{ "op": "<NAME>", ... }` — a
13
+ discriminated union on `op`. Most ops can wrap an `input` filter; leaf ops
14
+ (`ALL`, `LAYER`, `LUCENE`, `VARIABLE`) cannot.
15
+
16
+ ## Schema landmines (READ FIRST)
17
+
18
+ The five things that bite first-time TAS authors:
19
+
20
+ 1. **There is no `EQ` op.** Equality goes through `ATTRIBUTE` with `operator: IN` (one or more values), or through `LUCENE` with `field:value` syntax. Reaching for `{op:"EQ"}` is the most common day-1 mistake.
21
+ 2. **`AND` / `OR` cannot be empty.** `{op:"AND", input:[]}` returns HTTP 400. Always at least one child. Schema validation rejects empty arrays before the request reaches the server.
22
+ 3. **`NOT` takes a single `input`, not an array.** `{op:"NOT", input: <filter>}` — NOT `input: [<filter>]`. The latter parses but is rejected.
23
+ 4. **`{op:"ALL"}` without `limit` returns the entire topology.** Often megabytes; sometimes refused. Always pair `ALL` with a sensible `limit` (5–100 for sampling).
24
+ 5. **Field name is `input`, not `filters`/`children`.** The recursive child slot is always called `input` (singular for NOT, array for AND/OR/TRAVERSE-input).
25
+
26
+ Two more, schema-shape:
27
+
28
+ 6. **`LUCENE` is tenant-config-dependent** — not enabled on every tenant. If you're authoring a query that should work everywhere, prefer `ATTRIBUTE` + `MATCHES` instead.
29
+ 7. **`LAYER` filter has both `value` (singular string) and `values` (array)** — pick the one that matches the count of layers you want to match. Both work; mixing them is invalid.
30
+
31
+ ## The envelope
32
+
33
+ ```jsonish
34
+ {
35
+ "filter": { ... }, // root filter tree (required in practice)
36
+ "limit": 20, // cap returned vertices
37
+ "projection": "DETAILED", // attribute breadth: DETAILED | BRIEF | NO_TYPE
38
+ "includeServices": true, // surface the `serviceNames` attribute on each vertex
39
+ "includeStatus": true, // adds a `states[]` array to the response (NOT an attribute on each vertex — see the Status section in tas-cookbook)
40
+ "time": 1700000000000, // optional point-in-time epoch ms
41
+ "order": [...], // optional sort
42
+ "universe": { ... }, // optional filter applied first
43
+ "postFilter": { ... } // optional filter applied after
44
+ }
45
+ ```
46
+
47
+ Default `projection` is implementation-defined; explicitly set `DETAILED`
48
+ when you want all attributes back.
49
+
50
+ **`includeServices: true` is the cheapest way to learn what services an entity belongs to** — every entity carries a `serviceNames: string[]` attribute that the platform pre-populates (typically within ~1 min of entity creation, ~2 min of new-service creation). Without this flag, the field is silently absent and you'll wrongly conclude the entity has no service membership. Pair with `includeStatus: true` for an identity + membership + health snapshot in one query.
51
+
52
+ **`includeStatus: true` adds a `states[]` array to the response, separate from `vertices[]` / `edges[]`.** It does NOT add a `status` attribute to each vertex — read severity by joining `states[].vertexId` against `vertices[].id`. Each state row is per-`(vertex, alert OR metric)`; a single vertex typically has multiple state rows. The rolled-up severity (what the platform UI shows) lives on the row whose `stateExternalId.alert === "sa://sa_status"`. Numeric `status` values: `0=UNKNOWN`, `1=OK`, `2=MINOR`, `3=MAJOR`, `4=CRITICAL`. Full response shape, common patterns, and the "show me everything currently CRITICAL" workaround in `cookbooks/tas-cookbook` ("Status — `includeStatus` and the `states[]` response array" section).
53
+
54
+ ## The 8 ops you'll use most
55
+
56
+ | Op | Purpose | Has `input`? |
57
+ |---|---|---|
58
+ | `ALL` | Match every vertex. Use with `limit` for sampling. | No |
59
+ | `ATTRIBUTE` | Match by attribute expressions. The workhorse. | Yes |
60
+ | `LAYER` | Restrict to one or more layers. | No |
61
+ | `LUCENE` | Free-text Lucene query. | No |
62
+ | `AND` / `OR` | Compose. Each takes `input: TasFilter[]`. **Cannot be empty.** | Yes (children) |
63
+ | `NOT` | Negate. Takes `input: TasFilter`. | Yes |
64
+ | `TRAVERSE` | Walk edges. Takes a `traverse: [...]` array. | Yes |
65
+
66
+ ## Discovery first, then author
67
+
68
+ Before authoring anything specific, call:
69
+
70
+ - `discovery_layers` → list of available layers (e.g. `INFRASTRUCTURE`, `CONNECTOR`, `AGENT`)
71
+ - `discovery_attributes(layer)` → attribute names known on that layer
72
+ - `discovery_attribute_values(layer, attribute)` → distinct values for IN-style filters
73
+
74
+ Without this, you'll guess attribute names that don't exist on this tenant.
75
+
76
+ **Authoring an `ATTRIBUTE` filter (or any other op)?** Call `query_schema` with the op first to confirm the canonical field names — `{type: "tas", op: "ATTRIBUTE"}` returns a 4 KB summary listing the 5 properties (op, input, expressions, layer, mode) with descriptions. Cheaper than a guess + server-validation retry, and prevents the textbook `_type` vs `type` mistake. The summary is inline-readable; reach for `full: true` only when nested validation detail (enum values past 6 entries, recursive sub-shapes) actually matters.
77
+
78
+ ## Pattern: layer + attribute filter
79
+
80
+ ```json
81
+ {
82
+ "filter": {
83
+ "op": "AND",
84
+ "input": [
85
+ { "op": "LAYER", "values": ["INFRASTRUCTURE"] },
86
+ { "op": "ATTRIBUTE", "expressions": [
87
+ { "name": "type", "operator": "IN", "values": ["HOST"] }
88
+ ]}
89
+ ]
90
+ },
91
+ "limit": 20,
92
+ "projection": "DETAILED"
93
+ }
94
+ ```
95
+
96
+ ## Pattern: traverse from one set to its neighbours
97
+
98
+ ```json
99
+ {
100
+ "filter": {
101
+ "op": "TRAVERSE",
102
+ "input": { "op": "ATTRIBUTE", "expressions": [...] },
103
+ "traverse": [
104
+ { "vertex": { "op": "ALL" }, "edge": { "op": "ALL" }, "direction": "FORWARD" }
105
+ ]
106
+ }
107
+ }
108
+ ```
109
+
110
+ ## ATTRIBUTE expression details
111
+
112
+ ```json
113
+ {
114
+ "name": "hostname", // attribute name
115
+ "operator": "MATCHES", // IN | NOT_IN | MATCHES | NOT_MATCHES | GE | GT | LE | LT
116
+ "values": ["api-*"], // values array (IN/NOT_IN take arrays of values)
117
+ "comparator": "LEXICAL", // LEXICAL | NUMBER | DATETIME (changes value typing)
118
+ "caseInsensitive": false
119
+ }
120
+ ```
121
+
122
+ For `comparator: "NUMBER"`, `values` are JSON numbers, not strings.
123
+
124
+ ## Iteration
125
+
126
+ Once a draft is in place, use `run_partial_query` with `at: ["filter", "input", N]`
127
+ to verify a sub-tree without authoring a separate test query. The wrapped
128
+ envelope inherits `limit`, `projection`, `time`, `universe`, `order`, `offset`
129
+ from the parent payload — so "run just this branch" sees what would be seen
130
+ at the top.
131
+
132
+ ## See also
133
+
134
+ - `tas-cookbook.md` — full op reference, recipe catalog, composition patterns
135
+ - `gotchas.md` — FROM_TOPOLOGY's restricted querySpecifier, ATTRIBUTE.layer constraint
136
+ - `discovery-flow.md` — full discovery pattern
137
+ - `run-query-vs-run-partial.md` — when to use which execution mode
138
+ - Live examples: `corpus_list("queries", {type: "tas"})` — fetch full payloads with `corpus_get("queries", "<id>")`. Good starting points: `01-discover-vertices`, `02-discover-services`, `10-filter-attribute-matches`, `11-filter-and-compose`.
@@ -0,0 +1,41 @@
1
+ ## Let's just say it out loud: time formatting from the command line sucks.
2
+
3
+ But there are some easy consistent options for many time range commands including
4
+
5
+ * metric data
6
+ * agent get-trace-summaries
7
+
8
+ The absolutely easiest way, IMO is `ISO Durations`.
9
+
10
+ The commands above take
11
+
12
+ * endTime + relativeStartTime
13
+ * startTime + relativeEndTime
14
+
15
+ ## Let's start with examples:
16
+
17
+ ### Time period ends 1day+3 hours ago, and begins 2 hours before that.
18
+ ```
19
+ endTime=P1DT3H relativeStartDuration=PT2H
20
+ ```
21
+
22
+ ### Time period starts 1week+7hours ago and ends 30 minutes after that.
23
+ ```
24
+ startTime=P1WT3H relativeEndDuration=PT30M
25
+ ```
26
+
27
+ * If you specify a partial for endTime or startTime, that is relative to NOW.
28
+ * relativeStartDuration/relativeEndDuration is relative to the endTime/startTime.
29
+ * There is no need to specify a negative
30
+
31
+ * P = REQUIRED START INDICATOR FOR ISO8601 Partial
32
+ * Y = years
33
+ * M = months
34
+ * W = weeks
35
+ * D = days
36
+ * T = delineator between dates and times, necessary to disambiguate between months and minutes
37
+ * H = hours
38
+ * M = minutes
39
+ * S = seconds
40
+
41
+
@@ -0,0 +1,2 @@
1
+ TurnOn: ${flagName}
2
+
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
2
+ <rect x="3" y="5" width="18" height="11" rx="1.5"/>
3
+ <line x1="3" y1="13" x2="21" y2="13"/>
4
+ <line x1="8" y1="20" x2="16" y2="20"/>
5
+ <line x1="12" y1="16" x2="12" y2="20"/>
6
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
2
+ <polyline points="3 17 9 11 13 14 21 6"/>
3
+ <polyline points="15 6 21 6 21 12"/>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">
2
+ <circle cx="12" cy="12" r="3.2"/>
3
+ <path d="M12 4v3M12 17v3M4 12h3M17 12h3M6.3 6.3l2.1 2.1M15.6 15.6l2.1 2.1M6.3 17.7l2.1-2.1M15.6 8.4l2.1-2.1"/>
4
+ </svg>
@@ -0,0 +1,113 @@
1
+ # `dx-do ui start` — visual query builder
2
+
3
+ Start a local Fastify + Angular server that lets you author and run **TAS / NASSQL / Metrics-Metadata** queries against a bound DXO2 tenant in your browser. The same server hosts the MCP endpoint at `/mcp` (see `dx-do help agentic-mcp` for the MCP surface).
4
+
5
+ > **Experimental.** `ui start` is currently gated. To run it, either:
6
+ > - pass `--enable-experimental-commands` on the dx-do invocation
7
+ > - export `DXDO_ENABLE_EXPERIMENTAL_COMMANDS=true` in your environment
8
+ >
9
+ > Both forms work the same way; the env var is the easiest if you'll be running ui repeatedly.
10
+
11
+ ## Usage
12
+
13
+ ```
14
+ DXDO_ENABLE_EXPERIMENTAL_COMMANDS=true dx-do ui start [config=<alias>]
15
+ [port=<n>]
16
+ [open=true|false]
17
+ [mcp=true|false]
18
+ [module.<id>=off|read|write ...]
19
+ [dev=true|false]
20
+ [mcpOnly=true|false]
21
+ ```
22
+
23
+ All flags are optional. With no flags the server picks a free port, opens your browser, prompts you to pick a tenant config, and starts the MCP at `/mcp`.
24
+
25
+ ## What you get
26
+
27
+ * **Visual editors** for the three datastore query types — TAS topology queries, NASSQL metric pipelines, and Metrics-Metadata specifiers. Each editor renders the payload tree with op-specific controls and discovery-driven dropdowns.
28
+ * **Tenant picker** (the *configuration alias* pill in the top bar). Switch tenants mid-session without restarting; everything re-binds.
29
+ * **Save to disk** under `~/.dxdo/queries/<alias>/` as a *file triplet* (see below). Saved queries appear in the left rail and can be edited / re-run later.
30
+ * **Discovery panel** — auto-loaded layer / service / metric / attribute lists for the bound tenant, cached per session. Refresh with the refresh button when the tenant changes underneath you.
31
+ * **Catalog browser** — read-only access to the universal worked-example queries and cookbooks shipped with `@dx-do/corpus`. Useful when you want a starting point for authoring.
32
+ * **MCP endpoint at `/mcp`** for AI agents — same 17-tool default surface as `dx-do agentic mcp`, gated by the same module flags. Use `mcp=false` to skip MCP entirely.
33
+
34
+ ## Basic workflow
35
+
36
+ 1. **Start**: `dx-do ui start config=demo-prod` (browser opens automatically).
37
+ 2. **Pick a query type** in the left rail or open an existing one.
38
+ 3. **Edit** in the visual tree, in the JSON5 tab, or both (they round-trip).
39
+ 4. **Run** with the ▶ button. Use the per-op ▶ buttons for partial runs (TAS sub-filters; NASSQL up-to-step).
40
+ 5. **Save** with **⌘S** / **Ctrl+S**. The file triplet is written to disk and the left-rail entry refreshes.
41
+
42
+ ## Query persistence — the file triplet
43
+
44
+ Each saved query is **three sibling files** under `~/.dxdo/queries/<alias>/`:
45
+
46
+ | File | Contents |
47
+ |---|---|
48
+ | `<id>.<type>.data-store.json5` | Payload + path-keyed inline descriptions persisted as JSON5 `/* */` block comments. |
49
+ | `<id>.<type>.data-store-tmd.json` | Test metadata: short description, tags, `expectedFailure`, `skip`. |
50
+ | `<id>.<type>.md` | Companion markdown — long-form intent, expected output, gotchas. |
51
+
52
+ `<type>` is `tas`, `nassql`, or `metadata`. The id includes a numeric prefix (e.g. `01-discover-vertices`) which orders the left rail. Files round-trip: hand-edit the JSON5 in your editor and the SPA picks up the changes on focus.
53
+
54
+ ## Inline descriptions — three tiers
55
+
56
+ Every op in your query can carry an inline note. The notes persist as JSON5 block comments and round-trip through the visual / JSON5 tabs without flapping.
57
+
58
+ * **Top-level** — file-leading comment, describes the whole query. Above the visual tree.
59
+ * **Per-op** — above each op's header (in the visual tree). Bound to a JSONPath like `$.filter` or `$.query[2]`.
60
+ * **Per-record** — above each AttributeExpression / specifier inside an op (e.g. `$.filter.expressions[0]`).
61
+
62
+ These descriptions are how you ground future agents reading your saved query via MCP — leave reasoning here and the next agent gets it for free via `get_query`.
63
+
64
+ ## Right pane — Source / Results / Debug
65
+
66
+ The right pane is tabbed:
67
+
68
+ * **Source** — pretty-printed JSON of the parsed payload. The default tab.
69
+ * **Results** — full-run output. Auto-activates when ▶ produces a result.
70
+ * **Debug** — partial-run output. Auto-activates when a per-op ▶ runs. Shows a scope breadcrumb (e.g. `$.filter.input[1]` for TAS, `steps 1–3` for NASSQL).
71
+
72
+ Tabs report `<n>ms / stale / error`. Editing the payload flips Results and Debug to **stale** until you re-run.
73
+
74
+ ## Flags
75
+
76
+ | Flag | Default | Effect |
77
+ |---|---|---|
78
+ | `config=<alias>` | (prompts in UI) | Pre-bind to `~/.dxdo/<alias>.dxo2.config.json`. |
79
+ | `port=<n>` | free port (4321 in `dev=true`) | Bind to a specific port. |
80
+ | `open=false` | `true` | Suppress the auto-open browser. |
81
+ | `mcpOnly=true` | `false` | Don't open browser; surface the MCP URL in the startup log. |
82
+ | `mcp=false` | `true` | Skip registering `/mcp` on the HTTP server entirely. |
83
+ | `module.<id>=off\|read\|write` | `ui=write`, others `read` | Per-module MCP permissions. See `dx-do help agentic-mcp` for the module corpus. |
84
+ | `dev=true` | `false` | Bind port 4321; enable CORS for `http://localhost:4200` (the Angular dev server). |
85
+
86
+ ## MCP module flags
87
+
88
+ The same `module.<id>=...` flags accepted by `dx-do agentic mcp` work here — they control the HTTP `/mcp` endpoint instead of stdio. Examples:
89
+
90
+ ```sh
91
+ # Lock external agents to read-only on user queries even though the SPA can still write.
92
+ dx-do ui start config=demo-prod module.ui=read
93
+
94
+ # Disable the MCP entirely (SPA only).
95
+ dx-do ui start config=demo-prod mcp=false
96
+ ```
97
+
98
+ The startup log line shows the resolved per-module levels so you can confirm at a glance.
99
+
100
+ ## Stopping
101
+
102
+ **Ctrl+C** terminates the server. The Fastify shutdown hook closes open connections cleanly.
103
+
104
+ ## Where things live on disk
105
+
106
+ * **Tenant configs** — `~/.dxdo/<alias>.dxo2.config.json`
107
+ * **Saved queries** — `~/.dxdo/queries/<alias>/[<folder>/]<id>.<type>.<ext>`
108
+ * **Catalog (read-only)** — bundled inside `@dx-do/corpus` (no user-side files)
109
+
110
+ ## Related
111
+
112
+ * `dx-do help agentic-mcp` — same MCP surface, stdio transport, no SPA.
113
+ * `dx-do help configuration` — how `~/.dxdo/<alias>.dxo2.config.json` files are loaded and validated.
@@ -0,0 +1,47 @@
1
+ ---
2
+ id: universe
3
+ title: universe — APM Universe vs O2 Universe
4
+ aliases: [universes, view, scope]
5
+ category: scoping
6
+ related: [service, application]
7
+ tags: [overloaded, core]
8
+ ---
9
+
10
+ # universe
11
+
12
+ DXO2 has **two flavors of universe**, and the difference matters for which API to call and what data to expect:
13
+
14
+ - **APM Universe** — ApmUniverseService territory. Tends to hold telemetry sources (the agents that produce metrics) and their associated entities. Created and managed by the APM side of the platform.
15
+ - **O2 Universe** (a.k.a. Platform Universe) — O2UniverseService territory. A catch-all for organization, especially data integrated from non-APM sources (NetOps, log analytics, custom integrations). Created and managed on the O2/platform side.
16
+
17
+ Both are **scoping mechanisms** — like a workspace for a slice of tenant data.
18
+
19
+ ## Why this matters
20
+
21
+ - The two flavors have **different APIs and different vertex shapes**. If you query the wrong service, you'll get an empty list and not realize it.
22
+ - Some system-default universes exist on every tenant and are usually NOT what the user wants when they say "in universe X" — e.g. `UNsaasProd`, `VIEWALL`. Exclude these from offered choices unless the user explicitly references them.
23
+
24
+ ## Disambiguation rule
25
+
26
+ 1. If the user names a universe by id or label, search **both** APM and O2 universes.
27
+ 2. The MCP tool `discovery_universes` returns the union (in two distinguishable lists).
28
+ 3. Default to the matching universe; if both have a universe of that name, prefer the user-created one and confirm.
29
+
30
+ ## When to scope by universe vs by service
31
+
32
+ - **Universe** = primary scope for *what data exists* (a slice of the tenant).
33
+ - **Service** = secondary scope for *organizational/business meaning* on top of a universe.
34
+
35
+ When a user says "the production environment", that's usually a universe (or a service inside a universe). "The X application" usually maps to a service or DXO2 application within whatever universe makes sense.
36
+
37
+ ## How users phrase it
38
+
39
+ - "in the APM universe" / "the metric universe" → APM Universe.
40
+ - "the platform universe" / "everything we ingest" → O2 Universe.
41
+ - "the production view" / "the prod scope" → either; needs disambiguation.
42
+
43
+ ## See also
44
+
45
+ - `cookbooks/universes-and-scopes` — full mechanics.
46
+ - `lexicon/service` — the next-axis-down.
47
+ - `entities/universe` — entity-shape detail.
@@ -0,0 +1,91 @@
1
+ ---
2
+ id: universe
3
+ title: Universe — the primary scoping mechanism for tenant data
4
+ synonyms: [view, scope, segregation]
5
+ related_entities: [service, dxi_service]
6
+ related_cookbooks: [universes-and-scopes, investigator-flow]
7
+ tags: [scoping, core, organizational-axis]
8
+ ---
9
+
10
+ # Universe
11
+
12
+ ## What it is
13
+
14
+ A **Universe** is the primary scoping mechanism in DXO2 — a named, access-controlled view over a slice of the tenant's topology and metrics. When a user asks an investigative question on a typical tenant, *the first ambiguity to resolve is which universe(s) they mean*. Universes are how customers segregate environments (prod vs staging), regions (NA vs EMEA vs APJ), product lines, lines of business, or any other organizational axis they care about.
15
+
16
+ There are **two distinct kinds of universes** in DXO2 with materially different shapes — confusing them silently is one of the bigger ways an investigator can hand back a wrong answer:
17
+
18
+ - **APM Universe** (legacy-shaped, APM-flavoured)
19
+ - **O2 Universe** (modern, "Platform" / O2-flavoured)
20
+
21
+ Both kinds can coexist on the same tenant. Many tenants have only one kind; some have both.
22
+
23
+ ## APM Universes
24
+
25
+ The original universe concept, scoped to APM (Application Performance Management) data.
26
+
27
+ **Shape**: each universe has a single `viewId` + `label`, and a fixed `views` object with three slots:
28
+
29
+ - `views.tas` — a TAS filter (in legacy form: `{ vertices, items, joins }`) defining which entities are visible.
30
+ - `views.nass` — a NASS filter built from EXACT-name and REGEX specifiers.
31
+ - `views.mm` — a metric-metadata filter (just a `string[]`).
32
+
33
+ Plus per-view permissions, attributes (counts like `TAS_AGENT_COUNT` / `TAS_ATC_COUNT` / `NASS_COUNT`), and an `access` block of users + groups with role-based permissions.
34
+
35
+ **How to enumerate**: from an MCP-driven agent, call `discovery_universes` (returns both kinds in one call as `{apm, o2}`, in the user-facing `name`-first shape). From the CLI: `dx-do apm-universe list`. Programmatically: `ApmUniverseService.retrieveAllUniverses()`.
36
+
37
+ **APM-flavoured signals**: legacy TAS filter shape (`legacy.vertices`, `legacy.items`, `legacy.joins`); presence of `attributes.TAS_AGENT_COUNT`; user/group permissions include `nass`/`tas`/`mm` keys.
38
+
39
+ ## O2 Universes
40
+
41
+ The newer Platform / O2-style universe. Same conceptual role (named, access-controlled view) but a flexible multi-view shape:
42
+
43
+ **Shape**: each universe has `viewId` + `label`/`description` (in `attributes`), and a `views: O2UniverseView[]` array — each entry is one of:
44
+
45
+ - `{ type: 'tas', filter: { filter: TASFilter, includeMetricFilter?, projection?, projectionFilter? }, permissions }`
46
+ - `{ type: 'nass', filter: { filter: TASFilter, serviceFilter? }, permissions }`
47
+ - `{ type: 'es', filter: unknown, permissions }`
48
+
49
+ A single O2 universe can carry zero, one, or many of each view type. The TAS filter inside is the *modern* TAS schema (op-discriminated tree), not the legacy form. Per-view permissions are independent.
50
+
51
+ **How to enumerate**: same as above — `discovery_universes` returns both kinds in one call. CLI: `dx-do o2-universe list`. Programmatically: `O2UniverseService.retrieveAllUniverses()`.
52
+
53
+ **O2-flavoured signals**: modern TAS filter shape (`op: 'AND'`, `op: 'ATTRIBUTE'`, etc.); `viewId` + `attributes.label`; multiple views in an array; the universe-to-service relationship surfaced via `getServiceNameToUniverseLabelMap()` (see "Universes and services" below).
54
+
55
+ ## Investigative checklist (the load-bearing pattern)
56
+
57
+ When a user asks an entity- or metric-shaped investigative question (*"are there any hosts with high CPU right now?"*, *"show me the top services by error rate"*, *"what alarms fired overnight?"*), **before authoring any query**:
58
+
59
+ 1. **Enumerate**: how many APM universes? how many O2 universes? how many top-level services?
60
+ 2. **Surface**: tell the user what you see, in a single sentence. *"On this tenant I see 3 APM universes (Prod, Staging, NA-EMEA-Combined), 7 O2 universes (mostly per-region), and 142 services."*
61
+ 3. **Ask**: did they mean *all* of it, a specific universe, a specific service?
62
+ 4. **Default carefully**: if the user replies "all hosts", confirm whether they mean "literally all" (cross-universe) or "all in the universe I'm currently looking at" — the answer is materially different on a tenant with multiple universes.
63
+
64
+ This is one or two extra round-trips. It's worth it; the alternative is producing a query against the wrong scope and burning the user's time on a result they have to re-do.
65
+
66
+ ## Universes and services
67
+
68
+ On many O2 tenants, a universe maps to a *service* (or a service maps to a universe — the relationship is bidirectional). `O2UniverseService.getServiceNameToUniverseLabelMap()` and `getUniverseLabelToServiceNameMap()` exist for exactly this lookup. When a user names a service in their question (*"the Mobile Service"*), check whether there's a universe of the same name first — if so, the universe-scoped query is usually what they want.
69
+
70
+ See `entities/service` for the service axis (which has its own hierarchy and subservice-traversal nuances).
71
+
72
+ ## Common synonyms / mistakes
73
+
74
+ - **"View" / "scope"** — colloquial synonyms. Worth confirming which kind of universe.
75
+ - **"Universe" without qualifier** — on a multi-universe-kind tenant, ALWAYS clarify APM vs O2. They have different filter shapes, different access models, and different downstream behavior.
76
+ - **Confusing universe with service** — common, especially because they often share names. A *universe* is the view-defining filter; a *service* is one of the things that view typically scopes around. They're orthogonal axes that frequently collapse together in tenant naming.
77
+ - **Treating `attributes.label` and `viewId` interchangeably** — the user reads the label; the API takes the viewId. Always look up the viewId via the universe list, don't hardcode it. The `discovery_universes` MCP tool surfaces these as `name` (label) and `id` (viewId) — speak to users in `name` always, reach for `id` only when assembling an outgoing API call.
78
+
79
+ ## Useful CLI commands
80
+
81
+ - `dx-do apm-universe list` — APM universes on the bound tenant.
82
+ - `dx-do o2-universe list` — O2 universes on the bound tenant.
83
+ - `dx-do o2-universe services` — service↔universe mapping.
84
+ - `dx-do apm-universe detail` / `o2-universe export` — full universe shape including filters.
85
+
86
+ ## See also
87
+
88
+ - `entities/service` — the secondary scoping axis (often interacts with universes).
89
+ - `entities/dxi_service` — APM-internal service abstraction (different from the service axis).
90
+ - `cookbooks/universes-and-scopes` — the canonical investigator pattern for universe-aware querying.
91
+ - `cookbooks/investigator-flow` — the broader scope-clarification checklist.
@@ -0,0 +1,105 @@
1
+ ---
2
+ id: universes-and-scopes
3
+ title: Universes and scopes — APM vs O2 disambiguation
4
+ applies_to: all
5
+ tags: [investigator, scoping, reference]
6
+ related: [investigator-flow, service-hierarchies]
7
+ ---
8
+
9
+ # Universes and scopes
10
+
11
+ ## Why this matters
12
+
13
+ On any tenant with more than one universe, "show me the hosts" is ambiguous. The user almost always has a specific universe in mind but doesn't realize they're asking against an undefined scope. Authoring a query against the wrong scope is silently wrong — the user gets answers that look real but represent the wrong slice.
14
+
15
+ This cookbook covers the universe-disambiguation half of the scope-clarification step (`cookbooks/investigator-flow` step 1).
16
+
17
+ ## Two kinds of universes
18
+
19
+ DXO2 has **APM Universes** and **O2 Universes** (Platform). Both can coexist on a tenant. They have different shapes, different APIs, and different downstream behavior. See `entities/universe` for the schema-level details.
20
+
21
+ | | APM Universe | O2 Universe |
22
+ |---|---|---|
23
+ | Shape | Fixed `views: { tas, nass, mm }` | Flexible `views[]` (TAS / NASS / ES, multi-instance) |
24
+ | TAS filter form | Legacy (`vertices`, `items`, `joins`) | Modern op-discriminated tree |
25
+ | NASS filter form | EXACT/REGEX specifiers | TAS filter + optional ServiceFilter |
26
+ | Enumerate (CLI) | `dx-do apm-universe list` | `dx-do o2-universe list` |
27
+ | Service↔universe map | (per-universe; check the universe's `views` for service references) | Provided by the O2 universe metadata; surfaced via `discovery_universes` once available |
28
+
29
+ There is no shared "universe list" MCP tool today — `discovery_universes` is forthcoming. Until then, shell out to the CLI commands above.
30
+
31
+ ## How to detect "which kind does the user mean"
32
+
33
+ When the user mentions a universe name without qualifying it:
34
+
35
+ 1. **Check both lists.** A name might be unique to APM, unique to O2, or duplicated across both (rare but possible).
36
+ 2. **If unique to one** — proceed with that universe; mention which kind in your handoff sentence so the user can correct you if wrong.
37
+ 3. **If duplicated** — ask. *"There's an APM universe and an O2 universe both called 'Prod' — which one?"*
38
+ 4. **If neither matches** — ask if they're naming a service instead. Universes and services often have overlapping names (see "Universe-service collisions" below).
39
+
40
+ When the user uses APM-flavoured language (*"agents in this universe"*, *"the APM Prod universe"*, *"agent counts"*) — bias toward APM Universe.
41
+
42
+ When the user uses O2-flavoured language (*"the O2 view"*, *"the platform universe"*, *"NASS view permissions"*) — bias toward O2 Universe.
43
+
44
+ ## Universe-service collisions
45
+
46
+ On many O2-style tenants, **a universe and a service share the same name** because the universe was created from the service's filter (or vice versa). When the user says *"the Mobile Service"*:
47
+
48
+ - Is there a universe labelled "Mobile Service"? Cross-check the O2 universe list (`dx-do o2-universe list`) for a matching label.
49
+ - If yes, the universe-scoped query is usually the right move — universes already encode the relevant filter.
50
+ - If no, fall back to a service-scoped TAS query (see `cookbooks/service-hierarchies`).
51
+
52
+ If the user has both a universe and a service of the same name, that's an artifact of how their tenant was set up; the universe usually has the more curated definition.
53
+
54
+ ## Authoring queries scoped to a universe
55
+
56
+ A universe is a collection of *filter definitions* — to scope a TAS or NASSQL query to a universe, you replicate the universe's filter into your query.
57
+
58
+ ### From an O2 Universe
59
+
60
+ For an O2 Universe with a TAS view, retrieve the universe (e.g. via `dx-do o2-universe get <id>`), pull the TAS view's filter, and AND it with the user's intent filter:
61
+
62
+ ```jsonish
63
+ {
64
+ "filter": {
65
+ "op": "AND",
66
+ "input": [
67
+ <universe's TAS filter>,
68
+ <the user's intent filter>
69
+ ]
70
+ },
71
+ "limit": 100,
72
+ "projection": "DETAILED"
73
+ }
74
+ ```
75
+
76
+ For a NASS view, the universe carries `{ filter: TASFilter, serviceFilter?: ServiceFilter }` — for NASSQL queries, use the TAS filter as the input to `FROM_TOPOLOGY`.
77
+
78
+ ### From an APM Universe
79
+
80
+ The APM Universe carries a *legacy*-shaped TAS filter (`legacy.vertices`, `legacy.items`, `legacy.joins`). The DXO2 server typically accepts both forms; if the canonical TAS schema (op-discriminated) doesn't accept the legacy shape directly, you may need to translate it. A simpler practical approach: use the universe's `nass` filter (EXACT-name specifiers) as the input to `FROM_TOPOLOGY` in a NASSQL query when possible.
81
+
82
+ ## System-default universes — exclude when inferring org shape
83
+
84
+ Two universe IDs are tenant-creation defaults (not user-modeled scopes). They appear on every tenant; their presence tells you nothing about how the customer organizes their data:
85
+
86
+ - **`UNsaasProd`** — the APM default universe (often labelled "Your Applications").
87
+ - **`VIEWALL`** — the O2 default universe (often labelled "All Access").
88
+
89
+ When inferring the *organizational shape* of a tenant for an investigator's scope-clarification step, **filter these out** of the universe list. The user-created universes that remain are the ones that reflect the customer's intent (per-region, per-product, per-environment, etc.). If after filtering there are zero or one user-created universes, the tenant is universe-light — fall back on the service axis for org structure.
90
+
91
+ (For *executing* a query against a universe, the system defaults are still valid scopes; they just don't help you understand "how is this tenant organized.")
92
+
93
+ ## Investigator-flow integration
94
+
95
+ In step 1 of `cookbooks/investigator-flow`, surface the user-created universe count alongside the service count: *"On this tenant: 11 APM universes / 6 O2 universes (excluding the system defaults `UNsaasProd` and `VIEWALL`), 106 services across 24 root branches."* Then state the org-shape inference and ask one targeted question: *"Services look fully populated here, so I'd lean on the service axis — were you thinking of a specific service, or all of them?"*
96
+
97
+ If the user answers with a name that maps to a universe: scope the query to that universe.
98
+
99
+ If the user answers with a name that maps to a service: use `cookbooks/service-hierarchies` for the SERVICE filter pattern (preferred when both axes are populated — see `cookbooks/investigator-flow` § "Scope-axis precedence").
100
+
101
+ ## See also
102
+
103
+ - `entities/universe` — the schema-level reference.
104
+ - `cookbooks/service-hierarchies` — the service-axis half of scope clarification.
105
+ - `cookbooks/investigator-flow` — the broader investigator decision tree.
@@ -0,0 +1,31 @@
1
+ ---
2
+ id: vertex_entity_node
3
+ title: vertex / entity / node — same thing, three names
4
+ aliases: [topology node, graph node]
5
+ category: topology
6
+ related: []
7
+ tags: [overloaded]
8
+ ---
9
+
10
+ # vertex / entity / node
11
+
12
+ Three words for the same DXO2 concept: a record in the topology graph that represents a thing the platform tracks (a host, a transaction, a service, a database, …).
13
+
14
+ - **vertex** — the most precise term. Used in TAS APIs (`vertices`, `vertex.attr.type`).
15
+ - **entity** — used in cookbooks, docs, conversation. The corpus catalog section is `entities/`.
16
+ - **node** — used in Kubernetes shops to mean the worker node, but in graph contexts can mean the same as vertex. Avoid in DXO2 docs; prefer "vertex" for TAS and "entity" for narrative.
17
+
18
+ ## Conventions
19
+
20
+ - TAS query authoring → "vertex" (matches the API).
21
+ - Entity catalog browsing / cookbook prose → "entity".
22
+ - Talking to a Kubernetes user → "node" almost always means `k8s_NODE`. Don't conflate.
23
+
24
+ ## Edges
25
+
26
+ The companion concept — relationships between vertices — is just **edge** (no overload). Edges have attributes including `semantic` (`contains`, `agent-monitors`, `runs_on`, etc.). Some edges have no `semantic` value at all; see `cookbooks/entity-relationships`.
27
+
28
+ ## See also
29
+
30
+ - `entities/` — the catalog section.
31
+ - `cookbooks/entity-relationships` — edge taxonomy.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dx-do/cli",
3
- "version": "5.2.48",
3
+ "version": "5.2.50",
4
4
  "description": "CLI execution of DX Operational Observability operations and triage",
5
5
  "author": "Ki Alam",
6
6
  "logo": {