@superblocksteam/telemetry 2.0.173-next.4 → 2.0.174

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 (304) hide show
  1. package/dist/browser/console-logging.js +7 -2
  2. package/dist/browser/console-logging.js.map +1 -1
  3. package/dist/browser/early-console-buffer.js +14 -12
  4. package/dist/browser/early-console-buffer.js.map +1 -1
  5. package/dist/browser/index.js +41 -12
  6. package/dist/browser/index.js.map +1 -1
  7. package/dist/browser/init.d.ts +1 -1
  8. package/dist/browser/init.d.ts.map +1 -1
  9. package/dist/browser/init.js +52 -42
  10. package/dist/browser/init.js.map +1 -1
  11. package/dist/browser/instrumentations.js +15 -11
  12. package/dist/browser/instrumentations.js.map +1 -1
  13. package/dist/browser/logs.d.ts +1 -1
  14. package/dist/browser/logs.d.ts.map +1 -1
  15. package/dist/browser/logs.js +18 -11
  16. package/dist/browser/logs.js.map +1 -1
  17. package/dist/browser/metrics.js +12 -9
  18. package/dist/browser/metrics.js.map +1 -1
  19. package/dist/browser/resilient-exporter.d.ts +1 -1
  20. package/dist/browser/resilient-exporter.d.ts.map +1 -1
  21. package/dist/browser/resilient-exporter.js +12 -8
  22. package/dist/browser/resilient-exporter.js.map +1 -1
  23. package/dist/browser/sanitizer.js +6 -2
  24. package/dist/browser/sanitizer.js.map +1 -1
  25. package/dist/browser/traced-socket.js +18 -14
  26. package/dist/browser/traced-socket.js.map +1 -1
  27. package/dist/common/contracts/tier2-traces.js +44 -33
  28. package/dist/common/contracts/tier2-traces.js.map +1 -1
  29. package/dist/common/deployment-type.js +8 -5
  30. package/dist/common/deployment-type.js.map +1 -1
  31. package/dist/common/guardrails.js +38 -26
  32. package/dist/common/guardrails.js.map +1 -1
  33. package/dist/common/index.js +24 -8
  34. package/dist/common/index.js.map +1 -1
  35. package/dist/common/log-sanitizer.js +55 -37
  36. package/dist/common/log-sanitizer.js.map +1 -1
  37. package/dist/common/policy-evaluator.d.ts +1 -1
  38. package/dist/common/policy-evaluator.d.ts.map +1 -1
  39. package/dist/common/policy-evaluator.js +9 -5
  40. package/dist/common/policy-evaluator.js.map +1 -1
  41. package/dist/common/resource.js +25 -18
  42. package/dist/common/resource.js.map +1 -1
  43. package/dist/common/tier-hints.js +22 -12
  44. package/dist/common/tier-hints.js.map +1 -1
  45. package/dist/common/trace-sanitizer.js +10 -6
  46. package/dist/common/trace-sanitizer.js.map +1 -1
  47. package/dist/common/traced-socket-types.js +2 -1
  48. package/dist/common/traced-socket-types.js.map +1 -1
  49. package/dist/index.js +38 -6
  50. package/dist/index.js.map +1 -1
  51. package/dist/lint/forbidden-attributes.js +24 -19
  52. package/dist/lint/forbidden-attributes.js.map +1 -1
  53. package/dist/lint/index.js +8 -1
  54. package/dist/lint/index.js.map +1 -1
  55. package/dist/llmobs/index.js +9 -2
  56. package/dist/llmobs/index.js.map +1 -1
  57. package/dist/llmobs/tier1-exporter.js +12 -6
  58. package/dist/llmobs/tier1-exporter.js.map +1 -1
  59. package/dist/llmobs/tier2-summarizer.js +5 -1
  60. package/dist/llmobs/tier2-summarizer.js.map +1 -1
  61. package/dist/node/dynamic-attribute-processor.js +7 -2
  62. package/dist/node/dynamic-attribute-processor.js.map +1 -1
  63. package/dist/node/exporters/resilient-exporter.d.ts +1 -1
  64. package/dist/node/exporters/resilient-exporter.d.ts.map +1 -1
  65. package/dist/node/exporters/resilient-exporter.js +12 -8
  66. package/dist/node/exporters/resilient-exporter.js.map +1 -1
  67. package/dist/node/index.js +26 -7
  68. package/dist/node/index.js.map +1 -1
  69. package/dist/node/init.d.ts +3 -3
  70. package/dist/node/init.d.ts.map +1 -1
  71. package/dist/node/init.js +72 -66
  72. package/dist/node/init.js.map +1 -1
  73. package/dist/node/local-obs-mode.js +4 -1
  74. package/dist/node/local-obs-mode.js.map +1 -1
  75. package/dist/node/log-processor.d.ts +1 -1
  76. package/dist/node/log-processor.d.ts.map +1 -1
  77. package/dist/node/log-processor.js +55 -47
  78. package/dist/node/log-processor.js.map +1 -1
  79. package/dist/node/metrics-client.js +5 -1
  80. package/dist/node/metrics-client.js.map +1 -1
  81. package/dist/node/safe-logger.js +12 -8
  82. package/dist/node/safe-logger.js.map +1 -1
  83. package/dist/node/sanitizing-processor.d.ts +2 -2
  84. package/dist/node/sanitizing-processor.d.ts.map +1 -1
  85. package/dist/node/sanitizing-processor.js +10 -6
  86. package/dist/node/sanitizing-processor.js.map +1 -1
  87. package/dist/node/service-tracers.js +10 -7
  88. package/dist/node/service-tracers.js.map +1 -1
  89. package/dist/node/traced-socket.d.ts +3 -3
  90. package/dist/node/traced-socket.d.ts.map +1 -1
  91. package/dist/node/traced-socket.js +52 -48
  92. package/dist/node/traced-socket.js.map +1 -1
  93. package/dist/npm-registry/emitter.js +47 -34
  94. package/dist/npm-registry/emitter.js.map +1 -1
  95. package/dist/npm-registry/index.js +19 -3
  96. package/dist/npm-registry/index.js.map +1 -1
  97. package/dist/npm-registry/sanitize.js +27 -16
  98. package/dist/npm-registry/sanitize.js.map +1 -1
  99. package/dist/npm-registry/spans.js +12 -7
  100. package/dist/npm-registry/spans.js.map +1 -1
  101. package/dist/testing/in-memory-exporter.d.ts +1 -1
  102. package/dist/testing/in-memory-exporter.d.ts.map +1 -1
  103. package/dist/testing/in-memory-exporter.js +12 -6
  104. package/dist/testing/in-memory-exporter.js.map +1 -1
  105. package/dist/testing/index.js +15 -3
  106. package/dist/testing/index.js.map +1 -1
  107. package/dist/testing/metrics-capture.js +15 -12
  108. package/dist/testing/metrics-capture.js.map +1 -1
  109. package/dist/testing/test-init.js +31 -24
  110. package/dist/testing/test-init.js.map +1 -1
  111. package/dist/types/index.js +17 -1
  112. package/dist/types/index.js.map +1 -1
  113. package/dist/types/policy.js +24 -21
  114. package/dist/types/policy.js.map +1 -1
  115. package/dist-esm/browser/console-logging.d.ts +18 -0
  116. package/dist-esm/browser/console-logging.d.ts.map +1 -0
  117. package/dist-esm/browser/console-logging.js +27 -0
  118. package/dist-esm/browser/console-logging.js.map +1 -0
  119. package/dist-esm/browser/early-console-buffer.d.ts +49 -0
  120. package/dist-esm/browser/early-console-buffer.d.ts.map +1 -0
  121. package/dist-esm/browser/early-console-buffer.js +181 -0
  122. package/dist-esm/browser/early-console-buffer.js.map +1 -0
  123. package/dist-esm/browser/index.d.ts +18 -0
  124. package/dist-esm/browser/index.d.ts.map +1 -0
  125. package/dist-esm/browser/index.js +23 -0
  126. package/dist-esm/browser/index.js.map +1 -0
  127. package/dist-esm/browser/init.d.ts +100 -0
  128. package/dist-esm/browser/init.d.ts.map +1 -0
  129. package/dist-esm/browser/init.js +317 -0
  130. package/dist-esm/browser/init.js.map +1 -0
  131. package/dist-esm/browser/instrumentations.d.ts +67 -0
  132. package/dist-esm/browser/instrumentations.d.ts.map +1 -0
  133. package/dist-esm/browser/instrumentations.js +79 -0
  134. package/dist-esm/browser/instrumentations.js.map +1 -0
  135. package/dist-esm/browser/logs.d.ts +57 -0
  136. package/dist-esm/browser/logs.d.ts.map +1 -0
  137. package/dist-esm/browser/logs.js +80 -0
  138. package/dist-esm/browser/logs.js.map +1 -0
  139. package/dist-esm/browser/metrics.d.ts +29 -0
  140. package/dist-esm/browser/metrics.d.ts.map +1 -0
  141. package/dist-esm/browser/metrics.js +46 -0
  142. package/dist-esm/browser/metrics.js.map +1 -0
  143. package/dist-esm/browser/resilient-exporter.d.ts +43 -0
  144. package/dist-esm/browser/resilient-exporter.d.ts.map +1 -0
  145. package/dist-esm/browser/resilient-exporter.js +84 -0
  146. package/dist-esm/browser/resilient-exporter.js.map +1 -0
  147. package/dist-esm/browser/sanitizer.d.ts +35 -0
  148. package/dist-esm/browser/sanitizer.d.ts.map +1 -0
  149. package/dist-esm/browser/sanitizer.js +207 -0
  150. package/dist-esm/browser/sanitizer.js.map +1 -0
  151. package/dist-esm/browser/traced-socket.d.ts +102 -0
  152. package/dist-esm/browser/traced-socket.d.ts.map +1 -0
  153. package/dist-esm/browser/traced-socket.js +199 -0
  154. package/dist-esm/browser/traced-socket.js.map +1 -0
  155. package/dist-esm/common/contracts/tier2-traces.d.ts +116 -0
  156. package/dist-esm/common/contracts/tier2-traces.d.ts.map +1 -0
  157. package/dist-esm/common/contracts/tier2-traces.js +725 -0
  158. package/dist-esm/common/contracts/tier2-traces.js.map +1 -0
  159. package/dist-esm/common/deployment-type.d.ts +18 -0
  160. package/dist-esm/common/deployment-type.d.ts.map +1 -0
  161. package/dist-esm/common/deployment-type.js +27 -0
  162. package/dist-esm/common/deployment-type.js.map +1 -0
  163. package/dist-esm/common/guardrails.d.ts +132 -0
  164. package/dist-esm/common/guardrails.d.ts.map +1 -0
  165. package/dist-esm/common/guardrails.js +230 -0
  166. package/dist-esm/common/guardrails.js.map +1 -0
  167. package/dist-esm/common/index.d.ts +17 -0
  168. package/dist-esm/common/index.d.ts.map +1 -0
  169. package/dist-esm/common/index.js +17 -0
  170. package/dist-esm/common/index.js.map +1 -0
  171. package/dist-esm/common/log-sanitizer.d.ts +163 -0
  172. package/dist-esm/common/log-sanitizer.d.ts.map +1 -0
  173. package/dist-esm/common/log-sanitizer.js +745 -0
  174. package/dist-esm/common/log-sanitizer.js.map +1 -0
  175. package/dist-esm/common/policy-evaluator.d.ts +103 -0
  176. package/dist-esm/common/policy-evaluator.d.ts.map +1 -0
  177. package/dist-esm/common/policy-evaluator.js +196 -0
  178. package/dist-esm/common/policy-evaluator.js.map +1 -0
  179. package/dist-esm/common/resource.d.ts +79 -0
  180. package/dist-esm/common/resource.d.ts.map +1 -0
  181. package/dist-esm/common/resource.js +121 -0
  182. package/dist-esm/common/resource.js.map +1 -0
  183. package/dist-esm/common/tier-hints.d.ts +182 -0
  184. package/dist-esm/common/tier-hints.d.ts.map +1 -0
  185. package/dist-esm/common/tier-hints.js +199 -0
  186. package/dist-esm/common/tier-hints.js.map +1 -0
  187. package/dist-esm/common/trace-sanitizer.d.ts +82 -0
  188. package/dist-esm/common/trace-sanitizer.d.ts.map +1 -0
  189. package/dist-esm/common/trace-sanitizer.js +230 -0
  190. package/dist-esm/common/trace-sanitizer.js.map +1 -0
  191. package/dist-esm/common/traced-socket-types.d.ts +43 -0
  192. package/dist-esm/common/traced-socket-types.d.ts.map +1 -0
  193. package/dist-esm/common/traced-socket-types.js +16 -0
  194. package/dist-esm/common/traced-socket-types.js.map +1 -0
  195. package/dist-esm/index.d.ts +45 -0
  196. package/dist-esm/index.d.ts.map +1 -0
  197. package/dist-esm/index.js +56 -0
  198. package/dist-esm/index.js.map +1 -0
  199. package/dist-esm/lint/forbidden-attributes.d.ts +149 -0
  200. package/dist-esm/lint/forbidden-attributes.d.ts.map +1 -0
  201. package/dist-esm/lint/forbidden-attributes.js +210 -0
  202. package/dist-esm/lint/forbidden-attributes.js.map +1 -0
  203. package/dist-esm/lint/index.d.ts +9 -0
  204. package/dist-esm/lint/index.d.ts.map +1 -0
  205. package/dist-esm/lint/index.js +9 -0
  206. package/dist-esm/lint/index.js.map +1 -0
  207. package/dist-esm/llmobs/index.d.ts +22 -0
  208. package/dist-esm/llmobs/index.d.ts.map +1 -0
  209. package/dist-esm/llmobs/index.js +22 -0
  210. package/dist-esm/llmobs/index.js.map +1 -0
  211. package/dist-esm/llmobs/tier1-exporter.d.ts +146 -0
  212. package/dist-esm/llmobs/tier1-exporter.d.ts.map +1 -0
  213. package/dist-esm/llmobs/tier1-exporter.js +193 -0
  214. package/dist-esm/llmobs/tier1-exporter.js.map +1 -0
  215. package/dist-esm/llmobs/tier2-summarizer.d.ts +268 -0
  216. package/dist-esm/llmobs/tier2-summarizer.d.ts.map +1 -0
  217. package/dist-esm/llmobs/tier2-summarizer.js +652 -0
  218. package/dist-esm/llmobs/tier2-summarizer.js.map +1 -0
  219. package/dist-esm/node/dynamic-attribute-processor.d.ts +43 -0
  220. package/dist-esm/node/dynamic-attribute-processor.d.ts.map +1 -0
  221. package/dist-esm/node/dynamic-attribute-processor.js +74 -0
  222. package/dist-esm/node/dynamic-attribute-processor.js.map +1 -0
  223. package/dist-esm/node/exporters/resilient-exporter.d.ts +91 -0
  224. package/dist-esm/node/exporters/resilient-exporter.d.ts.map +1 -0
  225. package/dist-esm/node/exporters/resilient-exporter.js +132 -0
  226. package/dist-esm/node/exporters/resilient-exporter.js.map +1 -0
  227. package/dist-esm/node/index.d.ts +13 -0
  228. package/dist-esm/node/index.d.ts.map +1 -0
  229. package/dist-esm/node/index.js +13 -0
  230. package/dist-esm/node/index.js.map +1 -0
  231. package/dist-esm/node/init.d.ts +97 -0
  232. package/dist-esm/node/init.d.ts.map +1 -0
  233. package/dist-esm/node/init.js +359 -0
  234. package/dist-esm/node/init.js.map +1 -0
  235. package/dist-esm/node/local-obs-mode.d.ts +17 -0
  236. package/dist-esm/node/local-obs-mode.d.ts.map +1 -0
  237. package/dist-esm/node/local-obs-mode.js +19 -0
  238. package/dist-esm/node/local-obs-mode.js.map +1 -0
  239. package/dist-esm/node/log-processor.d.ts +132 -0
  240. package/dist-esm/node/log-processor.d.ts.map +1 -0
  241. package/dist-esm/node/log-processor.js +389 -0
  242. package/dist-esm/node/log-processor.js.map +1 -0
  243. package/dist-esm/node/metrics-client.d.ts +88 -0
  244. package/dist-esm/node/metrics-client.d.ts.map +1 -0
  245. package/dist-esm/node/metrics-client.js +205 -0
  246. package/dist-esm/node/metrics-client.js.map +1 -0
  247. package/dist-esm/node/safe-logger.d.ts +55 -0
  248. package/dist-esm/node/safe-logger.d.ts.map +1 -0
  249. package/dist-esm/node/safe-logger.js +154 -0
  250. package/dist-esm/node/safe-logger.js.map +1 -0
  251. package/dist-esm/node/sanitizing-processor.d.ts +67 -0
  252. package/dist-esm/node/sanitizing-processor.d.ts.map +1 -0
  253. package/dist-esm/node/sanitizing-processor.js +163 -0
  254. package/dist-esm/node/sanitizing-processor.js.map +1 -0
  255. package/dist-esm/node/service-tracers.d.ts +52 -0
  256. package/dist-esm/node/service-tracers.d.ts.map +1 -0
  257. package/dist-esm/node/service-tracers.js +78 -0
  258. package/dist-esm/node/service-tracers.js.map +1 -0
  259. package/dist-esm/node/traced-socket.d.ts +120 -0
  260. package/dist-esm/node/traced-socket.d.ts.map +1 -0
  261. package/dist-esm/node/traced-socket.js +334 -0
  262. package/dist-esm/node/traced-socket.js.map +1 -0
  263. package/dist-esm/npm-registry/emitter.d.ts +330 -0
  264. package/dist-esm/npm-registry/emitter.d.ts.map +1 -0
  265. package/dist-esm/npm-registry/emitter.js +546 -0
  266. package/dist-esm/npm-registry/emitter.js.map +1 -0
  267. package/dist-esm/npm-registry/index.d.ts +12 -0
  268. package/dist-esm/npm-registry/index.d.ts.map +1 -0
  269. package/dist-esm/npm-registry/index.js +12 -0
  270. package/dist-esm/npm-registry/index.js.map +1 -0
  271. package/dist-esm/npm-registry/sanitize.d.ts +174 -0
  272. package/dist-esm/npm-registry/sanitize.d.ts.map +1 -0
  273. package/dist-esm/npm-registry/sanitize.js +331 -0
  274. package/dist-esm/npm-registry/sanitize.js.map +1 -0
  275. package/dist-esm/npm-registry/spans.d.ts +61 -0
  276. package/dist-esm/npm-registry/spans.d.ts.map +1 -0
  277. package/dist-esm/npm-registry/spans.js +86 -0
  278. package/dist-esm/npm-registry/spans.js.map +1 -0
  279. package/dist-esm/package.json +1 -0
  280. package/dist-esm/testing/in-memory-exporter.d.ts +179 -0
  281. package/dist-esm/testing/in-memory-exporter.d.ts.map +1 -0
  282. package/dist-esm/testing/in-memory-exporter.js +250 -0
  283. package/dist-esm/testing/in-memory-exporter.js.map +1 -0
  284. package/dist-esm/testing/index.d.ts +9 -0
  285. package/dist-esm/testing/index.d.ts.map +1 -0
  286. package/dist-esm/testing/index.js +9 -0
  287. package/dist-esm/testing/index.js.map +1 -0
  288. package/dist-esm/testing/metrics-capture.d.ts +29 -0
  289. package/dist-esm/testing/metrics-capture.d.ts.map +1 -0
  290. package/dist-esm/testing/metrics-capture.js +71 -0
  291. package/dist-esm/testing/metrics-capture.js.map +1 -0
  292. package/dist-esm/testing/test-init.d.ts +80 -0
  293. package/dist-esm/testing/test-init.d.ts.map +1 -0
  294. package/dist-esm/testing/test-init.js +137 -0
  295. package/dist-esm/testing/test-init.js.map +1 -0
  296. package/dist-esm/types/index.d.ts +84 -0
  297. package/dist-esm/types/index.d.ts.map +1 -0
  298. package/dist-esm/types/index.js +7 -0
  299. package/dist-esm/types/index.js.map +1 -0
  300. package/dist-esm/types/policy.d.ts +92 -0
  301. package/dist-esm/types/policy.d.ts.map +1 -0
  302. package/dist-esm/types/policy.js +122 -0
  303. package/dist-esm/types/policy.js.map +1 -0
  304. package/package.json +17 -11
@@ -0,0 +1,725 @@
1
+ /**
2
+ * Tier 2 Traces Contract (v0.6.0) — TypeScript mirror.
3
+ *
4
+ * THIS FILE IS A MIRROR, NOT THE SOURCE OF TRUTH. The canonical Tier 2 traces
5
+ * contract lives in the `engineering` repo:
6
+ * - engineering/projects/o11y-refactor/contracts/tier2-traces.v0.6.0.json (canonical contract)
7
+ * - engineering/projects/o11y-refactor/contracts/README.md (rationale, Versioning Policy, Review Checklist)
8
+ * Org-wide telemetry naming and the Tier 2 privacy boundary are documented in the
9
+ * `workspace` repo: workspace/docs/naming-conventions.md and the `observability`
10
+ * skill (.agents/skills/observability/SKILL.md).
11
+ *
12
+ * CHANGING TIER 2 BEHAVIOR (forbidden / hashed / dropped / allowed attributes):
13
+ * 1. Update the canonical JSON in `engineering` FIRST, as a NEW version, per the
14
+ * README Versioning Policy (breaking = MAJOR, additive = MINOR, docs = PATCH).
15
+ * 2. Propagate the SAME change to every mirror so they stay byte-for-byte aligned:
16
+ * - this file (TS SDK sanitizer / ESLint / guardrails)
17
+ * - orchestrator/pkg/telemetry/forbidden_attributes.go (Go SDK maps)
18
+ * - orchestrator/pkg/telemetry/contracts/tier2-traces.json (Go embedded; regenerate via
19
+ * orchestrator/scripts/sync-ts-telemetry-contracts.sh — do not hand-edit)
20
+ * Editing this file alone silently drifts from the contract and the other SDKs, which
21
+ * lets a re-cased or newly added attribute bypass the Tier 2 privacy boundary. Cross-surface
22
+ * parity is enforced by the orchestrator Go tests (TestForbiddenAttributesMatchTSContract,
23
+ * TestDroppedAttributesMatchTS).
24
+ *
25
+ * Used by: trace-sanitizer (which spans/attributes to export), lint/forbidden-attributes
26
+ * (ESLint), guardrails (dev-time warnings), and Collector config generation.
27
+ * "request handler *" is a local extension for Express instrumentation (not in the JSON).
28
+ */
29
+ import { DeploymentTypeEnum } from "@superblocksteam/shared";
30
+ export function getAttributeName(attr) {
31
+ return typeof attr === "string" ? attr : attr.name;
32
+ }
33
+ /**
34
+ * OTEL GenAI semantic conventions (gen_ai.*) are preferred; llm.* attribute names are legacy.
35
+ * Span names: gen_ai.request / gen_ai.tool_call / gen_ai.stream* (vite-plugin-file-sync LLMObsOtelExporter);
36
+ * llm.request / llm.tool_call / ai.streamText* are legacy aliases for the same shapes.
37
+ */
38
+ const GEN_AI_REQUEST_LIKE_ATTRIBUTES = [
39
+ { name: "error", type: "boolean" },
40
+ { name: "gen_ai.client.duration_ms", type: "number" },
41
+ { name: "gen_ai.client.time_to_first_token", type: "number" },
42
+ {
43
+ name: "gen_ai.error.category",
44
+ allowedValues: [
45
+ "aborted",
46
+ "api_error",
47
+ "auth_error",
48
+ "content_filter",
49
+ "context_length",
50
+ "none",
51
+ "network",
52
+ "quota",
53
+ "rate_limit",
54
+ "timeout",
55
+ "unknown",
56
+ "validation_error",
57
+ ],
58
+ },
59
+ {
60
+ name: "gen_ai.operation.name",
61
+ allowedValues: [
62
+ "chat",
63
+ "embeddings",
64
+ "execute_tool",
65
+ "generate_content",
66
+ "invoke_agent",
67
+ "text_completion",
68
+ ],
69
+ },
70
+ {
71
+ name: "gen_ai.provider.name",
72
+ allowedValues: [
73
+ "anthropic",
74
+ "aws.bedrock",
75
+ "azure.ai.inference",
76
+ "azure.ai.openai",
77
+ "cohere",
78
+ "deepseek",
79
+ "gcp.gemini",
80
+ "gcp.vertex_ai",
81
+ "groq",
82
+ "mistral_ai",
83
+ "openai",
84
+ ],
85
+ },
86
+ { name: "gen_ai.request.model", maxCardinality: 50 },
87
+ {
88
+ name: "gen_ai.request.status",
89
+ allowedValues: ["error", "success"],
90
+ },
91
+ {
92
+ name: "gen_ai.response.finish_reasons",
93
+ allowedValues: ["content_filter", "error", "length", "stop", "tool_calls"],
94
+ },
95
+ { name: "gen_ai.response.model", maxCardinality: 50 },
96
+ {
97
+ name: "gen_ai.system",
98
+ allowedValues: [
99
+ "anthropic",
100
+ "aws.bedrock",
101
+ "azure.ai.inference",
102
+ "azure.ai.openai",
103
+ "cohere",
104
+ "deepseek",
105
+ "gcp.gemini",
106
+ "gcp.vertex_ai",
107
+ "groq",
108
+ "mistral_ai",
109
+ "openai",
110
+ ],
111
+ },
112
+ { name: "gen_ai.usage.cached_tokens", type: "number" },
113
+ { name: "gen_ai.usage.input_tokens", type: "number" },
114
+ { name: "gen_ai.usage.output_tokens", type: "number" },
115
+ { name: "gen_ai.usage.reasoning_tokens", type: "number" },
116
+ { name: "gen_ai.usage.total_tokens", type: "number" },
117
+ { name: "llm.cached_tokens", type: "number" },
118
+ { name: "llm.cost_usd", type: "number" },
119
+ { name: "llm.duration_ms", type: "number" },
120
+ {
121
+ name: "llm.error_category",
122
+ allowedValues: [
123
+ "aborted",
124
+ "api_error",
125
+ "auth_error",
126
+ "content_filter",
127
+ "context_length",
128
+ "none",
129
+ "network",
130
+ "quota",
131
+ "rate_limit",
132
+ "timeout",
133
+ "unknown",
134
+ "validation_error",
135
+ ],
136
+ },
137
+ {
138
+ name: "llm.finish_reason",
139
+ allowedValues: ["content_filter", "error", "length", "stop", "tool_calls"],
140
+ },
141
+ { name: "llm.input_tokens", type: "number" },
142
+ { name: "llm.model", maxCardinality: 50 },
143
+ { name: "llm.output_tokens", type: "number" },
144
+ {
145
+ name: "llm.provider",
146
+ allowedValues: [
147
+ "anthropic",
148
+ "azure",
149
+ "bedrock",
150
+ "cohere",
151
+ "google",
152
+ "mistral",
153
+ "openai",
154
+ ],
155
+ },
156
+ { name: "llm.reasoning_tokens", type: "number" },
157
+ {
158
+ name: "llm.status",
159
+ allowedValues: ["error", "success"],
160
+ },
161
+ { name: "llm.time_to_first_token_ms", type: "number" },
162
+ { name: "llm.total_tokens", type: "number" },
163
+ "otel.status_code",
164
+ {
165
+ name: "superblocks.tier_hint",
166
+ allowedValues: ["include_tier3", "skip_export", "tier1_only"],
167
+ },
168
+ ];
169
+ const GEN_AI_TOOL_CALL_ATTRIBUTES = [
170
+ ...GEN_AI_REQUEST_LIKE_ATTRIBUTES,
171
+ { name: "tool.duration_ms", type: "number" },
172
+ {
173
+ name: "tool.error_category",
174
+ allowedValues: [
175
+ "execution_error",
176
+ "none",
177
+ "not_found",
178
+ "permission_denied",
179
+ "timeout",
180
+ "unknown",
181
+ "validation_error",
182
+ ],
183
+ },
184
+ { name: "tool.name", maxCardinality: 50 },
185
+ {
186
+ name: "tool.status",
187
+ allowedValues: ["error", "success"],
188
+ },
189
+ ];
190
+ const GEN_AI_STREAM_STEP_ATTRIBUTES = [
191
+ ...GEN_AI_REQUEST_LIKE_ATTRIBUTES,
192
+ { name: "step.number", type: "number" },
193
+ {
194
+ name: "step.type",
195
+ allowedValues: ["reasoning", "text", "thinking", "tool_call"],
196
+ },
197
+ ];
198
+ /**
199
+ * Span patterns from tier2-traces.v0.4.0.json.
200
+ * Suffix wildcard only: "HTTP POST *" matches "HTTP POST /api/..." or "POST /api/...".
201
+ */
202
+ export const TIER_2_TRACE_CONTRACT = [
203
+ {
204
+ name: "HTTP GET *",
205
+ allowedAttributes: [
206
+ "http.method",
207
+ { name: "http.route", maxCardinality: 150 },
208
+ "http.status_code",
209
+ "http.response_content_length",
210
+ { name: "http.flavor", allowedValues: ["1.0", "1.1", "2.0", "3.0"] },
211
+ ],
212
+ },
213
+ {
214
+ name: "HTTP POST *",
215
+ allowedAttributes: [
216
+ "http.method",
217
+ { name: "http.route", maxCardinality: 150 },
218
+ "http.status_code",
219
+ "http.response_content_length",
220
+ "http.request_content_length",
221
+ { name: "http.flavor", allowedValues: ["1.0", "1.1", "2.0", "3.0"] },
222
+ ],
223
+ },
224
+ {
225
+ name: "HTTP PUT *",
226
+ allowedAttributes: [
227
+ "http.method",
228
+ { name: "http.route", maxCardinality: 150 },
229
+ "http.status_code",
230
+ "http.response_content_length",
231
+ "http.request_content_length",
232
+ ],
233
+ },
234
+ {
235
+ name: "HTTP DELETE *",
236
+ allowedAttributes: [
237
+ "http.method",
238
+ { name: "http.route", maxCardinality: 150 },
239
+ "http.status_code",
240
+ "http.response_content_length",
241
+ ],
242
+ },
243
+ {
244
+ name: "HTTP PATCH *",
245
+ allowedAttributes: [
246
+ "http.method",
247
+ { name: "http.route", maxCardinality: 150 },
248
+ "http.status_code",
249
+ "http.response_content_length",
250
+ "http.request_content_length",
251
+ ],
252
+ },
253
+ {
254
+ name: "request handler *",
255
+ allowedAttributes: [
256
+ "http.method",
257
+ { name: "http.route", maxCardinality: 150 },
258
+ "http.status_code",
259
+ "http.response_content_length",
260
+ "http.request_content_length",
261
+ { name: "http.flavor", allowedValues: ["1.0", "1.1", "2.0", "3.0"] },
262
+ "express.route",
263
+ ],
264
+ },
265
+ {
266
+ name: "WS SERVER *",
267
+ allowedAttributes: [
268
+ { name: "messaging.system", allowedValues: ["ws", "websocket"] },
269
+ { name: "messaging.destination_kind", allowedValues: ["websocket"] },
270
+ { name: "ws.handler", maxCardinality: 80 },
271
+ ],
272
+ },
273
+ {
274
+ name: "WS CLIENT *",
275
+ allowedAttributes: [
276
+ { name: "messaging.system", allowedValues: ["ws", "websocket"] },
277
+ ],
278
+ },
279
+ {
280
+ name: "WS HANDLER *",
281
+ allowedAttributes: [
282
+ { name: "messaging.system", allowedValues: ["ws", "websocket"] },
283
+ { name: "messaging.destination_kind", allowedValues: ["websocket"] },
284
+ ],
285
+ },
286
+ {
287
+ name: "api.execute",
288
+ alwaysSample: true,
289
+ allowedAttributes: [
290
+ { name: "view-mode", allowedValues: ["edit", "deployed", "preview"] },
291
+ {
292
+ name: "api.status",
293
+ allowedValues: ["success", "error", "timeout", "cancelled"],
294
+ },
295
+ { name: "api.type", allowedValues: ["api", "workflow", "scheduled_job"] },
296
+ { name: "api.step_count", type: "number" },
297
+ { name: "api.duration_ms", type: "number" },
298
+ { name: "remote", allowedValues: ["true", "false"] },
299
+ "otel.status_code",
300
+ "otel.status_description",
301
+ ],
302
+ },
303
+ {
304
+ name: "api.step",
305
+ allowedAttributes: [
306
+ { name: "step.type", maxCardinality: 50 },
307
+ { name: "step.status", allowedValues: ["success", "error"] },
308
+ { name: "step.duration_ms", type: "number" },
309
+ { name: "step.retry_count", type: "number" },
310
+ "otel.status_code",
311
+ ],
312
+ },
313
+ {
314
+ name: "api.block.*",
315
+ allowedAttributes: [
316
+ { name: "block.type", maxCardinality: 30 },
317
+ { name: "block.status", allowedValues: ["success", "error"] },
318
+ ],
319
+ },
320
+ {
321
+ name: "plugin.*",
322
+ allowedAttributes: [
323
+ { name: "plugin.name", maxCardinality: 80 },
324
+ {
325
+ name: "plugin.event",
326
+ allowedValues: ["execute", "test", "metadata", "pre_delete"],
327
+ },
328
+ { name: "plugin.result", allowedValues: ["succeeded", "failed"] },
329
+ { name: "plugin.duration_ms", type: "number" },
330
+ "otel.status_code",
331
+ ],
332
+ },
333
+ {
334
+ name: "db.*",
335
+ allowedAttributes: [
336
+ {
337
+ name: "db.system",
338
+ allowedValues: [
339
+ "postgresql",
340
+ "mysql",
341
+ "mssql",
342
+ "mongodb",
343
+ "redis",
344
+ "snowflake",
345
+ "bigquery",
346
+ "databricks",
347
+ "dynamodb",
348
+ "sqlite",
349
+ ],
350
+ },
351
+ {
352
+ name: "db.operation",
353
+ allowedValues: ["select", "insert", "update", "delete", "other"],
354
+ },
355
+ { name: "db.name", maxCardinality: 50 },
356
+ "otel.status_code",
357
+ ],
358
+ },
359
+ {
360
+ name: "gen_ai.request",
361
+ description: "LLM API request (OTEL GenAI span name). Emitted by vite-plugin-file-sync LLMObsOtelExporter.",
362
+ allowedAttributes: GEN_AI_REQUEST_LIKE_ATTRIBUTES,
363
+ },
364
+ {
365
+ name: "gen_ai.stream",
366
+ description: "Streaming LLM session (OTEL GenAI span name). Emitted by LLMObsOtelExporter for ai.streamText.",
367
+ allowedAttributes: GEN_AI_REQUEST_LIKE_ATTRIBUTES,
368
+ },
369
+ {
370
+ name: "gen_ai.stream.step",
371
+ description: "Streaming LLM step (OTEL GenAI span name). Emitted by LLMObsOtelExporter for ai.streamText.step.",
372
+ allowedAttributes: GEN_AI_STREAM_STEP_ATTRIBUTES,
373
+ },
374
+ {
375
+ name: "gen_ai.tool_call",
376
+ description: "Tool/function call within GenAI workflow (OTEL GenAI span name). Emitted by LLMObsOtelExporter.",
377
+ allowedAttributes: GEN_AI_TOOL_CALL_ATTRIBUTES,
378
+ },
379
+ {
380
+ name: "llm.request",
381
+ description: "Legacy span name; prefer gen_ai.request.",
382
+ allowedAttributes: GEN_AI_REQUEST_LIKE_ATTRIBUTES,
383
+ },
384
+ {
385
+ name: "llm.tool_call",
386
+ description: "Legacy span name; prefer gen_ai.tool_call.",
387
+ allowedAttributes: GEN_AI_TOOL_CALL_ATTRIBUTES,
388
+ },
389
+ {
390
+ name: "ai.streamText",
391
+ description: "Legacy span name; prefer gen_ai.stream.",
392
+ allowedAttributes: [
393
+ "llm.model",
394
+ "llm.provider",
395
+ { name: "llm.step_count", type: "number" },
396
+ { name: "llm.total_tokens", type: "number" },
397
+ ],
398
+ },
399
+ {
400
+ name: "ai.streamText.step",
401
+ description: "Legacy span name; prefer gen_ai.stream.step.",
402
+ allowedAttributes: [
403
+ { name: "step.number", type: "number" },
404
+ {
405
+ name: "step.type",
406
+ allowedValues: ["reasoning", "text", "thinking", "tool_call"],
407
+ },
408
+ ],
409
+ },
410
+ {
411
+ name: "clark.session",
412
+ allowedAttributes: [
413
+ "session.duration_ms",
414
+ "session.step_count",
415
+ "session.llm_call_count",
416
+ "session.tool_call_count",
417
+ "session.total_tokens",
418
+ {
419
+ name: "session.outcome",
420
+ allowedValues: ["success", "error", "aborted"],
421
+ },
422
+ ],
423
+ },
424
+ {
425
+ name: "clark.debug_loop",
426
+ allowedAttributes: [
427
+ { name: "loop.iteration", type: "number" },
428
+ {
429
+ name: "loop.reason",
430
+ allowedValues: ["error_recovery", "validation_failure", "retry"],
431
+ },
432
+ { name: "loop.duration_ms", type: "number" },
433
+ ],
434
+ },
435
+ {
436
+ name: "grpc.*",
437
+ allowedAttributes: [
438
+ { name: "rpc.system", allowedValues: ["grpc"] },
439
+ { name: "rpc.service", maxCardinality: 50 },
440
+ { name: "rpc.method", maxCardinality: 100 },
441
+ { name: "rpc.grpc.status_code", type: "number" },
442
+ ],
443
+ },
444
+ {
445
+ name: "kafka.*",
446
+ allowedAttributes: [
447
+ { name: "messaging.system", allowedValues: ["kafka"] },
448
+ { name: "messaging.destination", maxCardinality: 50 },
449
+ {
450
+ name: "messaging.operation",
451
+ allowedValues: ["publish", "receive", "process"],
452
+ },
453
+ ],
454
+ },
455
+ {
456
+ name: "redis.*",
457
+ allowedAttributes: [
458
+ { name: "db.system", allowedValues: ["redis"] },
459
+ { name: "db.operation", maxCardinality: 30 },
460
+ ],
461
+ },
462
+ {
463
+ name: "fetch",
464
+ allowedAttributes: [
465
+ "http.method",
466
+ "http.status_code",
467
+ { name: "http.host", maxCardinality: 200 },
468
+ ],
469
+ },
470
+ {
471
+ name: "schedule.*",
472
+ allowedAttributes: [
473
+ {
474
+ name: "schedule.type",
475
+ allowedValues: ["cron", "interval", "one_time"],
476
+ },
477
+ {
478
+ name: "schedule.status",
479
+ allowedValues: ["success", "error", "skipped"],
480
+ },
481
+ ],
482
+ },
483
+ // SABS app-builder spans (v0.3.0) + bundle download span (v0.4.0)
484
+ {
485
+ name: "sabs.build",
486
+ allowedAttributes: [
487
+ { name: "build.id", maxCardinality: 10000 },
488
+ {
489
+ name: "build.outcome",
490
+ allowedValues: ["success", "failed"],
491
+ },
492
+ "otel.status_code",
493
+ "otel.status_description",
494
+ ],
495
+ },
496
+ {
497
+ name: "sabs.build.*",
498
+ allowedAttributes: [
499
+ { name: "build.id", maxCardinality: 10000 },
500
+ "otel.status_code",
501
+ "otel.status_description",
502
+ ],
503
+ },
504
+ // AGENT-2723: aggregate download span replacing ~511 per-file RPC spans
505
+ {
506
+ name: "sabs.bundle.download",
507
+ description: "Aggregate span for the full SABS bundle download. Replaces per-file spans; per-file metrics emitted as sabs.bundle.files_downloaded, sabs.bundle.bytes_downloaded, sabs.bundle.file_fetch_ms.",
508
+ allowedAttributes: [
509
+ { name: "files.count", type: "number" },
510
+ { name: "bytes.sum", type: "number" },
511
+ { name: "slowest.ms", type: "number" },
512
+ "otel.status_code",
513
+ "otel.status_description",
514
+ ],
515
+ },
516
+ ];
517
+ /**
518
+ * Cloud trace contract: match-all span name ("*") so no spans are dropped by name.
519
+ * Attribute allowlist is not used when attributeAllowlistPassthrough is true.
520
+ */
521
+ export const CLOUD_TRACE_CONTRACT = [
522
+ { name: "*", allowedAttributes: [] },
523
+ ];
524
+ /**
525
+ * Returns the trace contract (span definitions) for the given deployment type.
526
+ * Cloud: match-all so no traces are dropped by span name.
527
+ * Cloud-prem: Tier 2 contract (named spans only).
528
+ */
529
+ export function getTraceContract(deploymentType) {
530
+ switch (deploymentType) {
531
+ case DeploymentTypeEnum.CLOUD:
532
+ return CLOUD_TRACE_CONTRACT;
533
+ case DeploymentTypeEnum.CLOUD_PREM:
534
+ default:
535
+ return TIER_2_TRACE_CONTRACT;
536
+ }
537
+ }
538
+ // ---------------------------------------------------------------------------
539
+ // Forbidden / hashed / dropped attribute names (v0.6.0 JSON)
540
+ // ---------------------------------------------------------------------------
541
+ /** Forbidden in Tier 2 (forbiddenAttributes in contract). Collector strips these entirely. */
542
+ export const FORBIDDEN_TIER_2_SPAN_ATTRIBUTES = [
543
+ "llmobs.input",
544
+ "llmobs.output",
545
+ "prompt",
546
+ "code",
547
+ "code.path",
548
+ "code.function.name",
549
+ "tool_input",
550
+ "tool_output",
551
+ "tool.input",
552
+ "tool.output",
553
+ "file_path",
554
+ "file_content",
555
+ "file.path",
556
+ "file.content",
557
+ "db.statement",
558
+ "db.query.text",
559
+ "db.query_text",
560
+ "http.request.body",
561
+ "http.response.body",
562
+ "url.full",
563
+ "url.query",
564
+ "http.url",
565
+ "http.target",
566
+ "user-email",
567
+ "user.email",
568
+ "user_email",
569
+ "enduser.email",
570
+ // v0.5.0 (AGENT-3255): opaque product-resource identifiers are NOT forbidden.
571
+ // application-id/_id, api-id/_id, resource-id/_id, integration-id/_id,
572
+ // commit-id/_id, profile-id/_id are randomly generated UUIDv4 handles for
573
+ // non-person resources (no embedded PII or customer content), so they pass
574
+ // through. The per-user identifier (user-id/user.id/user_id) is hashed instead
575
+ // of forbidden — see HASHED_TIER_2_SPAN_ATTRIBUTES below. Resource NAMES
576
+ // (api-name, resource-name) and widget-type stay forbidden as customer content.
577
+ "api-name",
578
+ "api_name",
579
+ "api.name",
580
+ "resource-name",
581
+ "resource_name",
582
+ "resource.name",
583
+ "widget-type",
584
+ "widget_type",
585
+ "widget.type",
586
+ "branch",
587
+ "error.stack",
588
+ "exception.stacktrace",
589
+ "auth_token",
590
+ "api_key",
591
+ "api-key",
592
+ "api.key",
593
+ "authorization",
594
+ "cookie",
595
+ "x-api-key",
596
+ // APPS-4190: npm registry tokens. Bucketing in sanitize-npm-attributes.ts
597
+ // is the primary defense; this list is the lint/runtime backstop so a
598
+ // future emitter that names an attribute after the token is stripped.
599
+ "npm.token",
600
+ "npm_token",
601
+ "npm-token",
602
+ "npm.registry.token",
603
+ "npm.registry_token",
604
+ "registry_token",
605
+ "registry-token",
606
+ "registry.token",
607
+ ];
608
+ /**
609
+ * Hashed (keyed HMAC) for Tier 2 (hashedAttributes in contract).
610
+ * v0.5.0 (AGENT-3255): per-user / per-session identifiers single out a natural
611
+ * person (pseudonymous personal data even as a UUID), so pseudonymize rather than
612
+ * forbid. This is the full contract hashedAttributes set: enduser.id, session.id,
613
+ * and the user-id variants. organization-id is intentionally NOT hashed (single
614
+ * customer org per cloud-prem deployment → pass-through).
615
+ * NOTE: with no hashConfig, TraceSanitizer.hashValue() emits "[redacted]", so
616
+ * these fail closed and never flow raw until an HMAC key is provisioned.
617
+ */
618
+ export const HASHED_TIER_2_SPAN_ATTRIBUTES = [
619
+ "enduser-id",
620
+ "enduser.id",
621
+ "enduser_id",
622
+ "session-id",
623
+ "session.id",
624
+ "session_id",
625
+ "user-id",
626
+ "user.id",
627
+ "user_id",
628
+ ];
629
+ /**
630
+ * Dropped — high cardinality, no hash value (droppedAttributes in contract).
631
+ * The contract's dropped set also lists correlation/request/trace/execution ids,
632
+ * but those are dropped at the collector (and pass through at the SDK in
633
+ * pass-through mode); the SDK only hard-drops binding keys. v0.6.0 adds the
634
+ * dotted/kebab spellings of binding_keys for casing parity.
635
+ */
636
+ export const DROPPED_HIGH_CARDINALITY_ATTRIBUTES = [
637
+ "binding-keys",
638
+ "binding.keys",
639
+ "binding_keys",
640
+ ];
641
+ // ---------------------------------------------------------------------------
642
+ // Set views (for lint, guardrails: fast .has() lookup)
643
+ // ---------------------------------------------------------------------------
644
+ export const TIER2_FORBIDDEN_ATTRIBUTES = new Set(FORBIDDEN_TIER_2_SPAN_ATTRIBUTES);
645
+ export const TIER2_HASHED_ATTRIBUTES = new Set(HASHED_TIER_2_SPAN_ATTRIBUTES);
646
+ export const TIER2_DROPPED_ATTRIBUTES = new Set(DROPPED_HIGH_CARDINALITY_ATTRIBUTES);
647
+ // ---------------------------------------------------------------------------
648
+ // Per-deployment attribute sets (for trace-sanitizer)
649
+ // ---------------------------------------------------------------------------
650
+ /** Empty set used for cloud (relaxed policy: no drop, no hash, no forbidden). */
651
+ const EMPTY_ATTRIBUTE_SET = new Set();
652
+ /**
653
+ * Returns the Tier 2 trace attribute sets and contract options for the given deployment type.
654
+ * Cloud: relaxed policy (no attributes dropped/hashed), match-all span names, pass-through attributes.
655
+ * Cloud-prem: full Tier 2 contract (forbidden/dropped/hashed), named spans only, allowlist enforced.
656
+ */
657
+ export function getTraceSanitizerAttributeSets(deploymentType) {
658
+ const spanDefinitions = getTraceContract(deploymentType);
659
+ switch (deploymentType) {
660
+ case DeploymentTypeEnum.CLOUD:
661
+ return {
662
+ forbiddenAttributes: EMPTY_ATTRIBUTE_SET,
663
+ droppedAttributes: EMPTY_ATTRIBUTE_SET,
664
+ hashedAttributes: EMPTY_ATTRIBUTE_SET,
665
+ spanDefinitions,
666
+ attributeAllowlistPassthrough: true,
667
+ };
668
+ case DeploymentTypeEnum.CLOUD_PREM:
669
+ default:
670
+ return {
671
+ forbiddenAttributes: TIER2_FORBIDDEN_ATTRIBUTES,
672
+ droppedAttributes: TIER2_DROPPED_ATTRIBUTES,
673
+ hashedAttributes: TIER2_HASHED_ATTRIBUTES,
674
+ spanDefinitions,
675
+ // Enforce per-span allowlists for cloud-prem: attributes not explicitly
676
+ // listed in the span definition's allowedAttributes are dropped before
677
+ // forwarding to Superblocks' internal Datadog.
678
+ attributeAllowlistPassthrough: false,
679
+ };
680
+ }
681
+ }
682
+ // ---------------------------------------------------------------------------
683
+ // Always-sample and value patterns (v0.3.0 samplingPolicy + lint-time)
684
+ // ---------------------------------------------------------------------------
685
+ /** Spans that should ALWAYS be sampled (samplingPolicy.alwaysSampleSpans in contract). */
686
+ export const ALWAYS_SAMPLE_SPANS = new Set(["api.execute"]);
687
+ /**
688
+ * Patterns that indicate forbidden content in attribute values (e.g. secrets in strings).
689
+ * No ^/$ anchors so they match secrets embedded anywhere.
690
+ * It's not used by TraceSanitizer, only in guardrails.
691
+ */
692
+ export const FORBIDDEN_VALUE_PATTERNS = [
693
+ /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]+/,
694
+ /\b(sk|pk)-[a-zA-Z0-9]{32,}\b/,
695
+ /Bearer\s+[A-Za-z0-9._-]{20,}/,
696
+ /-----BEGIN\s+(RSA\s+)?(PRIVATE|PUBLIC)\s+KEY-----/,
697
+ /\bAKIA[A-Z0-9]{16}\b/,
698
+ /\b(ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b/,
699
+ // npm registry tokens (`npm_<36+ alphanumerics>`). The npm-name spec allows
700
+ // underscores, so without this pattern a token shaped like `npm_AAAA...`
701
+ // would slip through `sanitizeNpmPackageName` as a "valid" package name.
702
+ /\bnpm_[A-Za-z0-9]{36,}\b/,
703
+ /\b(api[_-]?key|apikey|secret[_-]?key|access[_-]?token)[=:]\s*[A-Za-z0-9_-]{20,}\b/i,
704
+ ];
705
+ // ---------------------------------------------------------------------------
706
+ // Helpers (for lint, guardrails)
707
+ // ---------------------------------------------------------------------------
708
+ export function isForbiddenAttribute(name) {
709
+ return TIER2_FORBIDDEN_ATTRIBUTES.has(name);
710
+ }
711
+ export function isHashedAttribute(name) {
712
+ return TIER2_HASHED_ATTRIBUTES.has(name);
713
+ }
714
+ export function isDroppedAttribute(name) {
715
+ return TIER2_DROPPED_ATTRIBUTES.has(name);
716
+ }
717
+ export function containsForbiddenPattern(value) {
718
+ if (typeof value !== "string")
719
+ return false;
720
+ return FORBIDDEN_VALUE_PATTERNS.some((pattern) => pattern.test(value));
721
+ }
722
+ export function shouldAlwaysSample(spanName) {
723
+ return ALWAYS_SAMPLE_SPANS.has(spanName);
724
+ }
725
+ //# sourceMappingURL=tier2-traces.js.map