@dx-do/cli 5.2.49 → 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,97 @@
1
+ ---
2
+ id: query-vs-analysis-separation
3
+ title: Query vs analysis separation — produce data-fetching queries by default
4
+ applies_to: all
5
+ tags: [investigator, reference, default-behavior]
6
+ related: [investigator-flow, nassql-quickstart]
7
+ ---
8
+
9
+ # Query vs analysis separation
10
+
11
+ ## The default
12
+
13
+ When a user asks an investigative question that involves a metric (CPU, memory, latency, error count, request rate, …), the investigator's default is:
14
+
15
+ > **Produce a query that returns the raw data the user cares about. Don't apply thresholds / aggregations / anomaly detection in the query itself unless the user explicitly named one. Hand the data to the ui (for human exploration) or to an analyzer (for automated thresholding).**
16
+
17
+ The same data shape supports many analyses; the same threshold collapses many shapes into a single boolean.
18
+
19
+ ## Why this matters — the load-bearing example
20
+
21
+ User asks: *"Are there any hosts with high CPU right now?"*
22
+
23
+ What "high" means is unspecified, and the right answer depends on the user's actual operational concern. Three common interpretations of *the same dataset*:
24
+
25
+ | Interpretation | What you'd ask the data | Maps to |
26
+ |---|---|---|
27
+ | **Momentary spike** | `1-of-30 datapoints over 90%` in last hour | Usually noise; investigator alerts only the curious |
28
+ | **Sustained pressure** | `all-of-30 datapoints over 70%` in last hour | Usually a real story; the load is constant |
29
+ | **SLO-shaped** | `peak over 95% in last 6 hours` | An SLO question; involves time aggregation |
30
+
31
+ A query that returns the raw CPU datapoints (one row per host per timestamp) supports all three. A query with `FILTER cpu > 90` baked in supports only the first, and **silently** — the user doesn't see "no hosts with sustained pressure", they see "no high-CPU hosts" and may walk away with the wrong conclusion.
32
+
33
+ ## When to threshold in the query anyway
34
+
35
+ Three legitimate reasons:
36
+
37
+ 1. **The user explicitly named a threshold.** *"Hosts with sustained CPU over 80%"* → bake `FILTER cpu > 80` into the NASSQL pipeline (and confirm "sustained" = window aggregation).
38
+ 2. **Result-set size would be unmanageable.** A naive query against a million-host tenant might return millions of datapoints. First, add a sane `limit` (or sample). Only add a value-filter if `limit` isn't enough.
39
+ 3. **The threshold is part of the entity definition.** *"Hosts that are unhealthy"* might map to `state IN ['CRITICAL', 'WARNING']` — that's an entity-level filter, not a metric threshold; bake it in.
40
+
41
+ ## Pattern catalog
42
+
43
+ ### Pattern: "are there any X with high Y"
44
+
45
+ Default shape: TAS query for X (entities), then NASSQL pipeline for Y values.
46
+
47
+ ```
48
+ TAS: type=HOST in <scope> ← saved as queries/host-list-<scope>
49
+ NASSQL: FROM_TOPOLOGY (host-list)
50
+ → JOIN_METADATA on cpu metrics
51
+ → FROM (datapoints, last 1h)
52
+ → KEEP host.name, ts, cpu
53
+ ```
54
+
55
+ Hand off: *"Saved as `15-cpu-by-host`. Open the query in ui to see the raw values; threshold there or hand to the analyzer."*
56
+
57
+ ### Pattern: "top N noisy metric sources"
58
+
59
+ NASSQL `FROM_METADATA` (definitions), GROUP, COUNT, TOP. Threshold-free; the "noisy" is just an ordering. Fine to apply `TOP n=10` because that's pagination, not analysis.
60
+
61
+ ### Pattern: "show me the trend"
62
+
63
+ NASSQL `FROM` (datapoints) with WINDOW + MEAN (or PERCENTILE). The aggregation IS the user's intent — they want a trend, not raw datapoints. Bake it in. Include the time window. Don't threshold.
64
+
65
+ ### Pattern: "X right now"
66
+
67
+ "Right now" → time window of last ~1h (the most-recent-N-minutes default). The user almost never wants a single point-in-time; they want recent data.
68
+
69
+ ### Pattern: "is there a problem with X"
70
+
71
+ This is a *yes/no* question that wants analysis, not data. Two options:
72
+
73
+ 1. **Surface as data + ask** — *"Here's the recent data for X. Define what 'problem' means and I'll threshold."* Works when the user is exploring.
74
+ 2. **Hand to analyzer** — *"I'll save the data query and have the analyzer apply standard thresholds (sustained over 80%, sudden change > 30%, etc.) and give you a yes/no."* Works when the user wants a quick verdict.
75
+
76
+ ## Handoff phrasing templates
77
+
78
+ After saving with `create_query`:
79
+
80
+ > *"Saved as `<id>`. Open `http://localhost:<port>/queries/<id>` in ui to refine the time window or thresholds."*
81
+
82
+ When passing to analyzer (forthcoming):
83
+
84
+ > *"Saved as `<id>`. Handed to the analyzer with default thresholds for [CPU / memory / latency / etc.]. It'll come back with anomaly flags + a written summary."*
85
+
86
+ ## Anti-patterns
87
+
88
+ - **Silent thresholding.** Hard-coding `cpu > 90` because "that's what high probably means" — the user doesn't see what fell out, may make wrong calls.
89
+ - **Threshold as a default for `limit`.** Don't threshold to control result size; use `limit` (or `TOP`/`BOTTOM`).
90
+ - **One-shot analysis when the user is exploring.** If the user might iterate on the query (refine the universe, change the time window), give them a query they can edit, not a paragraph of analysis.
91
+ - **Skipping the data query and going straight to analysis.** Especially when the user asked an investigative-shaped question — the saved query is the artifact they can re-run, share, attach to dashboards. The analysis is ephemeral.
92
+
93
+ ## See also
94
+
95
+ - `cookbooks/investigator-flow` — step 5 of the loop is this default.
96
+ - `cookbooks/nassql-quickstart` — source-op selection (`FROM_TOPOLOGY` vs `FROM_METADATA` vs `FROM`).
97
+ - `entities/universe`, `entities/service` — for the scoping side of the same investigative question.
@@ -0,0 +1,80 @@
1
+ ---
2
+ id: run-query-vs-run-partial
3
+ title: run_query vs run_partial_query — when to use which
4
+ applies_to: all
5
+ tags: [reference, execution]
6
+ related: [tas-quickstart, nassql-quickstart, gotchas]
7
+ ---
8
+
9
+ # `run_query` vs `run_partial_query`
10
+
11
+ Both execute against the bound tenant; both return the same `ExecuteResult` shape. The choice is about *what* you want to run — the full payload as authored, or a sub-portion for verification.
12
+
13
+ ## Short version
14
+
15
+ | You want to… | Use |
16
+ |---|---|
17
+ | Execute the user-facing query as a whole | `run_query` |
18
+ | Verify a sub-tree of TAS while debugging an authoring step | `run_partial_query(at: …)` |
19
+ | Verify a NASSQL pipeline truncated at step N | `run_partial_query(upToStep: N)` |
20
+ | Run an MM specifier alone | `run_query` (MM has no partial form) |
21
+
22
+ `run_partial_query` is **always** an authoring/debug tool — never the final execution. When you save a query (`create_query`), the saved payload is what `run_query` would execute, not a partial.
23
+
24
+ ## `run_query` — full execution
25
+
26
+ ```
27
+ run_query({type: "tas" | "nassql" | "metadata", payload: <full payload>})
28
+ ```
29
+
30
+ - Executes the payload as-is against the bound tenant.
31
+ - Returns the `ExecuteResult` envelope — `result` (the data), `error`, `validation`, `executionTimeMs`.
32
+ - Validates with the canonical Zod schema (`@dx-do/client/datastore/<type>`) before sending. Validation errors come back as `validation`, not `error`.
33
+ - **Don't pass an empty payload.** `{}` parses as valid but executes against the entire topology / metric catalog (often megabytes of result). See `gotchas.md` "run_query — empty payload silently dumps the whole topology" — the server-side preflight refuses three unbounded shapes, but don't lean on it.
34
+
35
+ ## `run_partial_query` — sub-tree / step-up-to execution
36
+
37
+ Two surfaces, one endpoint, two argument shapes:
38
+
39
+ ### TAS: `at` (path array)
40
+
41
+ ```
42
+ run_partial_query({type: "tas", payload: <full payload>, at: ["filter", "input", 1]})
43
+ ```
44
+
45
+ - `at` is a JSONPath array (NOT a string). Walks into the payload starting from the root; the addressed sub-filter is extracted and wrapped in an envelope.
46
+ - The wrapped envelope **inherits** `limit`, `projection`, `time`, `universe`, `order`, `offset` from the parent payload — so "run just this branch" sees the same projection/limit the user has at the top.
47
+ - Use when you want to verify a single op deep in a recursive TAS filter tree without authoring a separate test query.
48
+
49
+ ### NASSQL: `upToStep` (integer, 0-based)
50
+
51
+ ```
52
+ run_partial_query({type: "nassql", payload: <full payload>, upToStep: 2})
53
+ ```
54
+
55
+ - `upToStep` truncates `payload.query` to the first N+1 steps.
56
+ - Top-level `limit` and `authorizationView` are preserved.
57
+ - Use to inspect the intermediate tabular shape after each pipeline stage — invaluable when chaining FROM_X + JOIN_Y + GROUP + AGG + KEEP.
58
+
59
+ ### Metadata: not supported
60
+
61
+ There's no partial form for MM — a single specifier has no obvious slice point. Don't pass `at` or `upToStep` for `type: "metadata"`; the server returns a structured error.
62
+
63
+ ## When the user asks "show me the data" — full or partial?
64
+
65
+ If the user is iterating on authoring (mid-conversation, just discussed an op), `run_partial_query` is often the cheaper move — verify the sub-tree, then commit to a full run when you've sharpened it.
66
+
67
+ If the user is asking for the actual answer (saved query, end-of-conversation handoff), `run_query` against the full payload is what they want.
68
+
69
+ ## Common mistakes
70
+
71
+ - **Passing `at` as a string** — must be an array of `string | number` segments. `"$.filter.input[1]"` is the human-readable rendering; the wire format is `["filter", "input", 1]`.
72
+ - **Passing both `at` and `upToStep`** — exactly one. The other must be omitted (not null). Server rejects.
73
+ - **Passing `at` with a path that doesn't address a TAS filter** — e.g. pointing at a number or array element that isn't itself a filter. Server returns a structured error.
74
+ - **Using `run_partial_query` as the final execution** — it's a debug op. Save with `create_query` and `run_query` for the canonical run.
75
+
76
+ ## See also
77
+
78
+ - `gotchas.md` — empty-payload trap on `run_query`.
79
+ - `cookbooks/tas-quickstart` — TAS payload shape; sub-tree iteration with `run_partial_query`.
80
+ - `cookbooks/nassql-quickstart` — NASSQL pipeline shape + step-up-to truncation.
@@ -0,0 +1,133 @@
1
+ ---
2
+ id: service
3
+ title: Service — the secondary scoping axis (often hierarchical)
4
+ synonyms: [saService, business service]
5
+ related_entities: [universe, dxi_service, host]
6
+ related_cookbooks: [service-hierarchies, universes-and-scopes, investigator-flow]
7
+ tags: [scoping, core, organizational-axis, hierarchy]
8
+ ---
9
+
10
+ # Service
11
+
12
+ ## What it is
13
+
14
+ A **Service** in DXO2 is a named grouping of related entities (hosts, agents, business transactions, k8s resources, …) that represents a unit of business or operational meaning — usually a customer-facing application, a back-end system, or an internal capability. Services are the secondary scoping axis after universes; on tenants where universes don't segregate the data finely enough, services are how users carve the topology.
15
+
16
+ Services are **vertex `type: 'saService'`** in the topology graph. The full attributes:
17
+
18
+ | Attribute | What it carries |
19
+ |---|---|
20
+ | `name` | Human-readable service name (what `discovery_services` returns and what users say). |
21
+ | `state` | `ACTIVE` (vs deprecated/inactive variants). |
22
+ | `root_service` | Array of root service names — represents the **service's path back to root services**, i.e. the hierarchy. |
23
+ | `situationsIncludeChildServices` | Per-service flag — whether situations bubble through the hierarchy. |
24
+ | `tags`, `location`, `source` | Free-form taxonomy + provenance (e.g. `source: 'OI'` for services from Operational Intelligence). |
25
+ | `metrics[]` | Built-in service metrics: `service_risk`, `service_health`, `service_availability`. |
26
+ | `externalId` | Shape: `SA:<cohort-uuid>:<service-uuid>`. |
27
+
28
+ ## Hierarchies — the load-bearing nuance
29
+
30
+ Services are **frequently hierarchical**: a *Mobile Service* might have *EMEA Mobile* / *NA Mobile* / *APJ Mobile* as subservices, each of which might further decompose. The `root_service` attribute is a service's path back to its roots; subservice relationships are encoded as graph edges in the topology.
31
+
32
+ The hierarchy is a **DAG, not a tree** — a single child service can have multiple parents. The DXO2 model has no notion of edge-typed relationships (no "depends-on" vs "rolls-up-to" distinction); every parent-child link is the same kind. Be aware: descending into a parent that has shared children pulls **all** of those children, including subtrees of the *other* parents that share them.
33
+
34
+ When a user names a service in an investigative question — *"hosts for Mobile Service"* — the answer is materially different depending on whether they mean:
35
+
36
+ - **JUST the directly-named service** (`Mobile Service` only) — typically far fewer entities.
37
+ - **The named service AND all subservices** (`Mobile Service` + `EMEA Mobile` + `NA Mobile` + `APJ Mobile` + …) — typically much larger.
38
+
39
+ Both interpretations are common. Don't guess; ask.
40
+
41
+ ### How to enumerate
42
+
43
+ From an MCP-driven agent, call `discovery_service_hierarchy` (front-door, always loaded). It returns a DAG view in one call: `{totalServices, rootCount, edgeCount, multiParentChildren[], roots[], byName: {<lowercase-name>: {displayName, parents[], children[], tags[], leaf}}}`.
44
+
45
+ - Keys in `byName` are case-folded — lowercase any service name the user mentions before looking it up.
46
+ - Walk `children` to know what subscoping pulls in.
47
+ - Walk `parents` to know what broader scope a service sits inside.
48
+ - Check `multiParentChildren` for the warning case above.
49
+
50
+ For the bare flat list (just service names, no hierarchy), `discovery_services` is cheaper. Both share an upstream call but project differently.
51
+
52
+ ## The shortcut: the `serviceNames` attribute on entities
53
+
54
+ Every entity that the platform has assigned to one or more services carries a **`serviceNames`** attribute — an array of the service names it belongs to (e.g. `["NA_Billing", "NA_Provisioning", "APPService_NA_Provisioning"]`). It's a denormalized index that the platform keeps current automatically: typically populated **within ~1 minute** of an entity being created, and **within ~2 minutes** of a new service being created.
55
+
56
+ For "what services does X belong to" questions, this is the cheapest possible move — far cheaper than running `discovery_service_hierarchy` and joining membership client-side.
57
+
58
+ **Important: the attribute is not in the default projection.** Pass `includeServices: true` on the TAS query envelope and the `serviceNames` field will appear in `vertex.attributes`. With `BRIEF`/`DETAILED` projection alone (no `includeServices`), the field is silently absent — agents who skip the flag will conclude "this tenant doesn't track service membership", which is wrong.
59
+
60
+ ```json
61
+ {
62
+ "filter": { "op": "ATTRIBUTE", "expressions": [{ "name": "name", "values": ["host-001"], "operator": "EQ" }] },
63
+ "limit": 5,
64
+ "projection": "DETAILED",
65
+ "includeServices": true
66
+ }
67
+ ```
68
+
69
+ Some entity types reliably carry it (DXI_SERVICE, AGENT, BUSINESSTRANSACTION, k8s workloads, HOSTs that participate in services). A few legitimately have `serviceNames: null` (CONNECTOR, PRODUCT, ACN_CONFIG — these are platform-internal records that aren't service members). Both `null` and a non-empty array are normal; missing-from-the-payload-entirely usually means `includeServices` was not set.
70
+
71
+ The companion knob is `includeStatus: true` — same idea but for the `state`/`status` attribute, which is similarly omitted by default. Worth setting alongside `includeServices` when you want a one-shot "what is this entity, what services does it belong to, and is it healthy" snapshot.
72
+
73
+ ## The SERVICE filter (the load-bearing schema)
74
+
75
+ TAS has a dedicated `SERVICE` op for service-scoped queries:
76
+
77
+ ```json
78
+ {
79
+ "op": "SERVICE",
80
+ "values": ["Mobile Service"],
81
+ "includeServiceHierarchy": false,
82
+ "excludeSubServices": false
83
+ }
84
+ ```
85
+
86
+ | Knob | Default | Meaning |
87
+ |---|---|---|
88
+ | `values: string[]` | (required) | Service names to scope to. Multiple names = OR. |
89
+ | `includeServiceHierarchy: boolean` | `false` | Returns the service's hierarchy info alongside the matched entities. |
90
+ | `excludeSubServices: boolean` | `false` | When `true`, restricts to entities directly attached to the named service(s) only. When `false` or omitted, includes entities of all subservices too. |
91
+
92
+ The user's mental model and the schema knob have inverted polarity on subservices — a user saying *"include subservices"* maps to `excludeSubServices: false` (the default, not an opt-in). Be explicit about what you set, especially when the user said *"just the Mobile Service"* — that's `excludeSubServices: true`.
93
+
94
+ `includeServiceHierarchy` is independent and orthogonal — it controls whether the response carries hierarchy metadata, not what's matched.
95
+
96
+ ## Investigator pattern
97
+
98
+ For any investigative question naming a service:
99
+
100
+ 1. **Confirm the service exists**: it's in `discovery_services` (returns flat names).
101
+ 2. **Confirm the user's intent**: just the named service, or the service + its subservices? *"Did you want JUST the named service, or also its subservices? On this tenant `Mobile Service` has [N] subservices."* (You'll need a TAS query to count subservices — `discovery_services` is flat.)
102
+ 3. **Author with explicit knobs**: set `excludeSubServices` to whatever the user confirmed. Don't rely on default behavior — different consumers of the schema have different defaults.
103
+
104
+ For the **inverse direction** ("what services does this entity belong to") — read the entity's `serviceNames` attribute (with `includeServices: true`). Don't traverse, don't query the service hierarchy, don't enumerate. The attribute is the canonical answer.
105
+
106
+ ## Relationship to universes
107
+
108
+ Services and universes are both scoping axes, frequently overlapping in tenant naming conventions. On many tenants:
109
+
110
+ - A service of name X and a universe with label X coexist (one created from the other, or vice versa).
111
+ - `O2UniverseService.getServiceNameToUniverseLabelMap()` is the lookup — when a user names "X" check this map to detect which axis they probably mean. If both exist, ask.
112
+
113
+ See `entities/universe`.
114
+
115
+ ## Common synonyms / mistakes
116
+
117
+ - **"saService"** — internal vertex type name; the user-facing word is "service" or "business service."
118
+ - **"Service Hierarchy"** — refers to the parent-child structure, not the `includeServiceHierarchy` boolean.
119
+ - **`DXI_SERVICE`** — *different concept*. APM-internal service abstraction (lives in APM_INFRASTRUCTURE layer); see `entities/dxi_service`. A user saying "service" almost never means DXI_SERVICE.
120
+ - **Services with parent-of-multiple-roots** — a service can have multiple root_service entries; queries that assume a single-rooted tree will miss content.
121
+ - **Defaulting on `excludeSubServices`** — schema-level default behavior may differ from what a user expects. Be explicit.
122
+
123
+ ## Useful CLI commands
124
+
125
+ - `dx-do o2-universe services universeViewId=<id>` — services associated with an O2 universe.
126
+ - (No flat `dx-do service list` today; enumerate via `discovery_services` or a TAS query for `type: 'saService'`.)
127
+
128
+ ## See also
129
+
130
+ - `entities/universe` — primary scoping axis; often interacts with services.
131
+ - `entities/dxi_service` — APM-internal service abstraction (commonly confused with `service`).
132
+ - `cookbooks/service-hierarchies` — query patterns for navigating parent-child + subservice traversal.
133
+ - `cookbooks/investigator-flow` — the broader scope-clarification checklist.
@@ -0,0 +1,178 @@
1
+ ---
2
+ id: service-hierarchies
3
+ title: Service hierarchies — navigating parent-child + the subservice-traversal decision
4
+ applies_to: all
5
+ tags: [investigator, scoping, reference]
6
+ related: [investigator-flow, universes-and-scopes]
7
+ ---
8
+
9
+ # Service hierarchies
10
+
11
+ ## Why this matters
12
+
13
+ When a user names a service in an investigative question (*"hosts for Mobile Service"*), they could mean two materially different things:
14
+
15
+ - **Just the named service** — entities directly attached to `Mobile Service` only.
16
+ - **The named service + all subservices** — entities attached to `Mobile Service` + `EMEA Mobile` + `NA Mobile` + `APJ Mobile` + every level beneath.
17
+
18
+ Both are common and the result sets differ by an order of magnitude. The schema has explicit knobs for this — DON'T let it default silently. See `entities/service` for the SERVICE filter schema.
19
+
20
+ ## Gotcha — use the `SERVICE` op, not `type=saService` ATTRIBUTE
21
+
22
+ A `saService` vertex *exists* in the topology, but on most tenants filtering by
23
+
24
+ ```json
25
+ { "op": "ATTRIBUTE",
26
+ "expressions": [
27
+ { "name": "type", "operator": "IN", "values": ["saService"] },
28
+ { "name": "name", "operator": "IN", "values": ["Mobile Service"] }
29
+ ] }
30
+ ```
31
+
32
+ returns **zero matches**. Service-membership semantics — "the vertices that ARE this service" — are reachable only through the dedicated `SERVICE` op:
33
+
34
+ ```json
35
+ { "op": "SERVICE",
36
+ "values": ["Mobile Service"],
37
+ "excludeSubServices": false }
38
+ ```
39
+
40
+ Use that as the input to your `TRAVERSE` (or AND it with a `type` ATTRIBUTE expression to narrow). This is the single most common first-attempt failure when a new author tries to scope a topology query to a named service — burns one wasted iteration before pivoting. Reach for `SERVICE` first.
41
+
42
+ ## The SERVICE filter (recap)
43
+
44
+ ```json
45
+ {
46
+ "op": "SERVICE",
47
+ "values": ["Mobile Service"],
48
+ "includeServiceHierarchy": false,
49
+ "excludeSubServices": false
50
+ }
51
+ ```
52
+
53
+ | Knob | Default | When `true` | When `false`/omitted |
54
+ |---|---|---|---|
55
+ | `includeServiceHierarchy` | `false` | Include hierarchy metadata in the response | Don't include hierarchy metadata |
56
+ | `excludeSubServices` | `false` | Restrict to entities directly attached to the named service(s) | **Include subservices' entities too** |
57
+
58
+ **Polarity gotcha**: the user saying *"include subservices"* maps to `excludeSubServices: false` — i.e. the *default*. The user saying *"just this service"* maps to the explicit `excludeSubServices: true`. Always set the knob explicitly so future readers (and your future self) don't have to remember the polarity.
59
+
60
+ ## Asking the user the right way
61
+
62
+ Single targeted question:
63
+
64
+ > *"Did you want JUST `Mobile Service`, or `Mobile Service` and its subservices? On this tenant `Mobile Service` has [N] subservices."*
65
+
66
+ To get the [N], run a TAS query and count — no flat "list subservices of X" tool today (`discovery_services` returns flat names, no parents). Two common shapes:
67
+
68
+ ```json
69
+ // shape A: rely on saService.root_service to find descendants
70
+ { "op": "ATTRIBUTE",
71
+ "expressions": [
72
+ { "name": "type", "operator": "IN", "values": ["saService"] },
73
+ { "name": "root_service", "operator": "MATCHES", "values": ["Mobile Service"] }
74
+ ]
75
+ }
76
+ ```
77
+
78
+ ```json
79
+ // shape B: TRAVERSE from the service vertex through its hierarchy edges
80
+ { "op": "TRAVERSE",
81
+ "input": {
82
+ "op": "ATTRIBUTE",
83
+ "expressions": [
84
+ { "name": "type", "operator": "IN", "values": ["saService"] },
85
+ { "name": "name", "operator": "IN", "values": ["Mobile Service"] }
86
+ ]
87
+ },
88
+ "traverse": [
89
+ { "vertex": { "op": "ATTRIBUTE", "expressions": [{"name": "type", "operator": "IN", "values": ["saService"]}] },
90
+ "edge": { "op": "ALL" },
91
+ "direction": "FORWARD"
92
+ }
93
+ ]
94
+ }
95
+ ```
96
+
97
+ The `root_service` shape is cheaper (no traverse); the TRAVERSE shape gives you the actual graph and works across multi-rooted services.
98
+
99
+ ## Authoring the user's query
100
+
101
+ Once the user has confirmed scope, weave the SERVICE filter into the user's actual intent:
102
+
103
+ ### "Hosts for Mobile Service (just it)"
104
+
105
+ ```json
106
+ {
107
+ "filter": {
108
+ "op": "AND",
109
+ "input": [
110
+ { "op": "ATTRIBUTE",
111
+ "expressions": [
112
+ { "name": "type", "operator": "IN", "values": ["HOST"] }
113
+ ]
114
+ },
115
+ { "op": "SERVICE",
116
+ "values": ["Mobile Service"],
117
+ "excludeSubServices": true
118
+ }
119
+ ]
120
+ },
121
+ "limit": 100,
122
+ "projection": "DETAILED"
123
+ }
124
+ ```
125
+
126
+ ### "Hosts for Mobile Service and all subservices"
127
+
128
+ ```json
129
+ {
130
+ "filter": {
131
+ "op": "AND",
132
+ "input": [
133
+ { "op": "ATTRIBUTE",
134
+ "expressions": [
135
+ { "name": "type", "operator": "IN", "values": ["HOST"] }
136
+ ]
137
+ },
138
+ { "op": "SERVICE",
139
+ "values": ["Mobile Service"],
140
+ "excludeSubServices": false
141
+ }
142
+ ]
143
+ },
144
+ "limit": 100,
145
+ "projection": "DETAILED"
146
+ }
147
+ ```
148
+
149
+ Same shape; the only thing the user's choice changed is `excludeSubServices`.
150
+
151
+ ## Multiple services
152
+
153
+ `SERVICE.values` is an array — multiple services = OR. Useful when the user names siblings:
154
+
155
+ ```json
156
+ { "op": "SERVICE",
157
+ "values": ["EMEA Mobile", "NA Mobile", "APJ Mobile"],
158
+ "excludeSubServices": false
159
+ }
160
+ ```
161
+
162
+ If the user names a parent + asks to exclude one subservice, that's an `AND(SERVICE(parent, includeSubs), NOT(SERVICE(excluded, includeSubs)))` shape.
163
+
164
+ ## Service vs universe
165
+
166
+ If the named "service" is also the name of a universe (common — see `cookbooks/universes-and-scopes`), the universe-scoped query is usually preferable: it carries a richer, curated filter than the bare SERVICE op. Cross-check the universe list (e.g. `dx-do o2-universe list`) for a label that matches the service name.
167
+
168
+ ## Anti-patterns
169
+
170
+ - **Defaulting to `excludeSubServices: undefined`** — relies on schema-level default (which is `false` = include subs) but reads as "I didn't think about it." Set the knob explicitly.
171
+ - **Confusing `includeServiceHierarchy` with subservice-inclusion** — the names are similar; `includeServiceHierarchy` is about response metadata, not what's matched.
172
+ - **Using TAS `TRAVERSE` when `SERVICE` will do** — the SERVICE op is purpose-built for this; reach for TRAVERSE only when you need the actual graph relationships in the result.
173
+
174
+ ## See also
175
+
176
+ - `entities/service` — full SERVICE filter schema + the `saService` vertex shape.
177
+ - `cookbooks/universes-and-scopes` — universe-side of scope clarification (often interacts).
178
+ - `cookbooks/investigator-flow` — the broader investigator decision tree.
@@ -0,0 +1,51 @@
1
+ ---
2
+ id: service
3
+ title: service — five things at once
4
+ aliases: [services, svc]
5
+ category: scoping
6
+ related: [application, dxi_service, host]
7
+ tags: [overloaded, disambiguation, core]
8
+ ---
9
+
10
+ # service
11
+
12
+ "Service" is one of the most overloaded terms in the DXO2 domain. When a user says "service X", they could mean any of these:
13
+
14
+ | Candidate | Description | Vertex type |
15
+ |---|---|---|
16
+ | **DXO2 service** | Organizational construct on the platform — a hierarchical group of entities, often created to model business or operational ownership. The default meaning. | (no specific vertex type — services are not vertices, they're an organizational axis) |
17
+ | **DXI_SERVICE** | APM-internal service abstraction. Aggregates an agent's traffic. Rarely the user's first interest. | `DXI_SERVICE` |
18
+ | **k8s_SERVICE** | Kubernetes Service — a network-routing object that exposes a set of pods. Common in cloud-native shops. | `k8s_SERVICE` |
19
+ | **AWS_ECS_FARGATE_SERVICE** | ECS Fargate service definition. AWS-specific. | `AWS_ECS_FARGATE_SERVICE` |
20
+ | **OS / system service** | Operating-system service (systemd, Windows Service). Rarely modeled as a vertex unless the customer has a specific integration. | (varies) |
21
+ | **business service** | A user-narrative service ("the checkout service") that may correspond to a DXO2 service, an APM application, a k8s deployment, or none of those. | (none — a label) |
22
+
23
+ ## Disambiguation rule
24
+
25
+ **Default to DXO2 service** unless the user's phrasing or context suggests otherwise. Specifically:
26
+
27
+ 1. If the name they used **matches a DXO2 service**, use that. (Use `discovery_search_by_name` or `discovery_services`.)
28
+ 2. If it doesn't match a DXO2 service but **matches an entity name with a more specific type** (`k8s_SERVICE` named `payments-svc`, an OS service, etc.), use that.
29
+ 3. If it matches multiple kinds, **show the user both** and ask, or run the query both ways.
30
+
31
+ ## How users phrase it
32
+
33
+ - "the X service" → almost always DXO2 service first; Kubernetes-shop second.
34
+ - "this k8s service" / "the cluster IP service" → `k8s_SERVICE`.
35
+ - "the application service" / "the APM service" → `DXI_SERVICE` (rare).
36
+ - "the systemd service" / "the windows service" → OS service.
37
+ - "the business service" → business label, may not have a vertex.
38
+
39
+ ## Quick path for "what DXO2 services does X belong to"
40
+
41
+ Every entity carries a `serviceNames` array attribute that the platform keeps current automatically (populated within ~1 min of entity creation, ~2 min of service creation). It's the cheapest way to answer "what services does X belong to" — no traversal, no hierarchy lookup.
42
+
43
+ The attribute is hidden behind a TAS envelope flag: pass `includeServices: true` and `serviceNames` shows up in `vertex.attributes`. Without it, the field is silently absent — leading the agent to think the tenant has no service membership. See `entities/service` for the canonical pattern.
44
+
45
+ ## See also
46
+
47
+ - `entities/service` — the DXO2 service.
48
+ - `entities/dxi_service` — APM-internal service.
49
+ - `entities/k8s_pod_and_container` (k8s_SERVICE catalog row) — k8s service.
50
+ - `lexicon/application` — closely-related overload.
51
+ - `cookbooks/service-hierarchies` — DXO2 service mechanics.
@@ -0,0 +1,76 @@
1
+ ---
2
+ id: servlet_or_frontend
3
+ title: Servlet / Frontend / Spring service — the APM "entry point" cluster
4
+ related_entities: [business_transaction, agent, database]
5
+ related_cookbooks: [investigator-flow]
6
+ tags: [apm, runtime-specific]
7
+ ---
8
+
9
+ # Servlet / Frontend / Spring service — entry-point cluster
10
+
11
+ This doc covers three closely-related vertex types that all describe **where a request enters an APM-instrumented app**:
12
+
13
+ - `SERVLET` — Java Servlet endpoint (Java APM agent).
14
+ - `GENERICFRONTEND` — generic frontend record (HTTP / gRPC / message handler) emitted when the agent recognizes traffic but the framework is not specifically known.
15
+ - `SPRINGSERVICE` — Spring-framework service endpoint (Java APM agent, Spring instrumentation).
16
+
17
+ `EXPRESSJS` (Node.js) and `BROWSER_APPLICATION` (RUM) are siblings of this cluster; they have their own catalog rows.
18
+
19
+ ## When to reach for which
20
+
21
+ | If the user asks about… | Filter type to… |
22
+ |---|---|
23
+ | "the API endpoints for X" | `GENERICFRONTEND` (most-general label) |
24
+ | "the servlets in the Java app" | `SERVLET` |
25
+ | "the Spring controllers" | `SPRINGSERVICE` |
26
+ | "this route in our Node app" | `EXPRESSJS` (sibling) |
27
+ | "the browser-side performance" | `BROWSER_APPLICATION` (sibling) |
28
+
29
+ When unclear, query all three with `ATTRIBUTE` `type IN [SERVLET, GENERICFRONTEND, SPRINGSERVICE]` and let the user disambiguate from the result.
30
+
31
+ ## What lives where
32
+
33
+ All three live in the **ATC** layer and share most of these attributes:
34
+
35
+ - `name` — endpoint label (path / class / method).
36
+ - `applicationName` — APM app the endpoint belongs to.
37
+ - `agent`, `agentDomain` — the producing agent.
38
+ - `processedBy`, `product` — provenance.
39
+ - `hostname` — the machine the agent runs on.
40
+
41
+ Type-specific detail attributes:
42
+
43
+ - `SERVLET`: `servletClassname`, `servletMethod`, sometimes `Build Date` / `Build Number`.
44
+ - `SPRINGSERVICE`: `ServiceName`, `Technology`.
45
+ - `GENERICFRONTEND`: `Experience`, `IsExperience`, `serviceId` (when wired into a DXO2 service), `deployment.environment.name`.
46
+
47
+ ## How metrics are reported
48
+
49
+ Per-endpoint response time, throughput, errors. Path shape under the agent:
50
+
51
+ - `Servlets|<servlet>:<metric>`
52
+ - `Frontends|<frontend>:<metric>`
53
+ - `<spring-namespace>|<service>:<metric>`
54
+
55
+ The path roots vary slightly by agent version and language SDK — when uncertain, use MM `discovery_metrics` filtered to the relevant `metric.source` and inspect the actual paths.
56
+
57
+ ## Relationship to BUSINESSTRANSACTION
58
+
59
+ A BT often passes through one or more of these endpoints. The BT is the logical end-to-end name; servlets/frontends are *touchpoints*. Common patterns:
60
+
61
+ - A BT named `Login` has `agent-monitors` edges to a `SERVLET` named `LoginServlet.doPost` and a `SPRINGSERVICE` named `AuthController.login` — the same logical work, two technology views.
62
+ - The same BT name can show up under multiple agents if the JVM is replicated; the BT vertex is one identity, the touchpoint vertices are per-agent.
63
+
64
+ When a user asks about "performance of the login flow", the right starting point is the BT (logical identity); when they ask about "the endpoint that's slow", start at the SERVLET / SPRINGSERVICE / GENERICFRONTEND level.
65
+
66
+ ## Common synonyms / mistakes
67
+
68
+ - "Endpoint" / "API" / "route" — usually `GENERICFRONTEND` but ambiguous with k8s_SERVICE, especially in cloud-native shops.
69
+ - "The login servlet" → `SERVLET`. "The login transaction" → `BUSINESSTRANSACTION`. They're related but distinct vertex types.
70
+ - Spring users sometimes say "service" when they mean `SPRINGSERVICE` — this is yet another collision with DXO2 `service`. See `lexicon/service`.
71
+
72
+ ## See also
73
+
74
+ - `entities/business_transaction` — the logical end-to-end view.
75
+ - `entities/agent` — the producing collector.
76
+ - `cookbooks/investigator-flow` — the BT vs touchpoint disambiguation.
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff" stroke="none">
2
+ <path d="M12 3 L21 21 L3 21 Z" fill-opacity="0.25" stroke="#fff" stroke-width="1.6" stroke-linejoin="round"/>
3
+ <text x="12" y="17" text-anchor="middle" font-family="Helvetica,Arial" font-size="8" font-weight="700" fill="#fff">A</text>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff" stroke="none">
2
+ <circle cx="12" cy="12" r="9" fill-opacity="0.25" stroke="#fff" stroke-width="1.6"/>
3
+ <text x="12" y="16" text-anchor="middle" font-family="Helvetica,Arial" font-size="8" font-weight="700" fill="#fff">X</text>
4
+ </svg>
@@ -0,0 +1,4 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#fff" stroke="none">
2
+ <rect x="3" y="3" width="18" height="18" rx="3" fill-opacity="0.25" stroke="#fff" stroke-width="1.6"/>
3
+ <text x="12" y="16" text-anchor="middle" font-family="Helvetica,Arial" font-size="8" font-weight="700" fill="#fff">D</text>
4
+ </svg>