@obsunified/collector 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/auth.d.ts +2 -0
  4. package/dist/auth.js +9 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/chunk-UGWDOGGH.js +319 -0
  7. package/dist/chunk-UGWDOGGH.js.map +1 -0
  8. package/dist/chunk-XKQTVIRE.js +671 -0
  9. package/dist/chunk-XKQTVIRE.js.map +1 -0
  10. package/dist/index.d.ts +1197 -0
  11. package/dist/index.js +17707 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/ingest-auth-HFVO1zIp.d.ts +165 -0
  14. package/dist/openai-FJYOQ7WO.js +384 -0
  15. package/dist/openai-FJYOQ7WO.js.map +1 -0
  16. package/package.json +73 -0
  17. package/src/ai-parity/ai-parity.acceptance.test.ts +449 -0
  18. package/src/analyses/derive.ts +642 -0
  19. package/src/analyses/index.ts +50 -0
  20. package/src/analyses/investigations.ts +277 -0
  21. package/src/analyses/tier0.ts +568 -0
  22. package/src/auth/dashboard-auth.ts +269 -0
  23. package/src/auth/ingest-auth.ts +147 -0
  24. package/src/durable-objects/tail-hub.test.ts +32 -0
  25. package/src/durable-objects/tail-hub.ts +158 -0
  26. package/src/framework/collector.ts +467 -0
  27. package/src/framework/env.ts +90 -0
  28. package/src/framework/logger.ts +81 -0
  29. package/src/index.ts +211 -0
  30. package/src/lib/action-aggregates.ts +1031 -0
  31. package/src/lib/action-identity.ts +106 -0
  32. package/src/lib/actions-store.ts +397 -0
  33. package/src/lib/ai-pricing.ts +80 -0
  34. package/src/lib/ai-store/calls.ts +148 -0
  35. package/src/lib/ai-store/evaluations.test.ts +47 -0
  36. package/src/lib/ai-store/evaluations.ts +125 -0
  37. package/src/lib/ai-store/helpers.ts +37 -0
  38. package/src/lib/ai-store/retention.ts +17 -0
  39. package/src/lib/ai-store/sessions.ts +277 -0
  40. package/src/lib/ai-store/spans.ts +109 -0
  41. package/src/lib/ai-store/types.ts +112 -0
  42. package/src/lib/ai-store.ts +76 -0
  43. package/src/lib/alerts-store.ts +458 -0
  44. package/src/lib/analyses-runner.ts +439 -0
  45. package/src/lib/analyses-store.test.ts +243 -0
  46. package/src/lib/analyses-store.ts +454 -0
  47. package/src/lib/ask.test.ts +302 -0
  48. package/src/lib/ask.ts +390 -0
  49. package/src/lib/blob-store-s3.ts +213 -0
  50. package/src/lib/blob-store.ts +366 -0
  51. package/src/lib/eval-cases-store.test.ts +171 -0
  52. package/src/lib/eval-cases-store.ts +1033 -0
  53. package/src/lib/evidence-references.test.ts +10 -0
  54. package/src/lib/evidence-references.ts +684 -0
  55. package/src/lib/hash.ts +26 -0
  56. package/src/lib/identity-index/action-lookups.ts +805 -0
  57. package/src/lib/identity-index/constants.ts +1 -0
  58. package/src/lib/identity-index/key-lookups.ts +199 -0
  59. package/src/lib/identity-index/mappers.ts +349 -0
  60. package/src/lib/identity-index/types.ts +196 -0
  61. package/src/lib/identity-index/user-lookup.ts +137 -0
  62. package/src/lib/identity-index.test.ts +624 -0
  63. package/src/lib/identity-index.ts +85 -0
  64. package/src/lib/json.ts +39 -0
  65. package/src/lib/llm.ts +263 -0
  66. package/src/lib/logs-store.ts +188 -0
  67. package/src/lib/metrics-store.test.ts +189 -0
  68. package/src/lib/metrics-store.ts +312 -0
  69. package/src/lib/narrate-gate.test.ts +260 -0
  70. package/src/lib/narrate-gate.ts +253 -0
  71. package/src/lib/openai.test.ts +300 -0
  72. package/src/lib/openai.ts +512 -0
  73. package/src/lib/otlp.ts +212 -0
  74. package/src/lib/parse-pprof.test.ts +64 -0
  75. package/src/lib/parse-pprof.ts +184 -0
  76. package/src/lib/payload-capture.ts +22 -0
  77. package/src/lib/projects-store.ts +207 -0
  78. package/src/lib/propagation-metric.test.ts +196 -0
  79. package/src/lib/propagation-metric.ts +175 -0
  80. package/src/lib/sql-db-dialect.test.ts +22 -0
  81. package/src/lib/sql-db-postgres.ts +229 -0
  82. package/src/lib/sql-db.ts +166 -0
  83. package/src/lib/stage6.test.ts +216 -0
  84. package/src/lib/store/export.ts +65 -0
  85. package/src/lib/store/helpers.ts +367 -0
  86. package/src/lib/store/ingest.ts +68 -0
  87. package/src/lib/store/issues.ts +158 -0
  88. package/src/lib/store/overview.ts +127 -0
  89. package/src/lib/store/retention.ts +10 -0
  90. package/src/lib/store/service-map.ts +384 -0
  91. package/src/lib/store/trace-detail.bench.ts +76 -0
  92. package/src/lib/store/trace-detail.test.ts +410 -0
  93. package/src/lib/store/trace-detail.ts +427 -0
  94. package/src/lib/store/trace-queries.test.ts +29 -0
  95. package/src/lib/store/trace-queries.ts +89 -0
  96. package/src/lib/store-overview.test.ts +77 -0
  97. package/src/lib/store.ts +96 -0
  98. package/src/lib/tail-publisher.ts +64 -0
  99. package/src/lib/test-utils/mem-sql-db.test.ts +93 -0
  100. package/src/lib/test-utils/mem-sql-db.ts +86 -0
  101. package/src/lib/ua-parser.ts +61 -0
  102. package/src/lib/usage-store.ts +567 -0
  103. package/src/migrations/001_telemetry_spans.sql +28 -0
  104. package/src/migrations/002_usage_events.sql +24 -0
  105. package/src/migrations/003_usage_analytics_columns.sql +13 -0
  106. package/src/migrations/004_logs.sql +19 -0
  107. package/src/migrations/005_ai_calls.sql +25 -0
  108. package/src/migrations/006_user_profiles.sql +11 -0
  109. package/src/migrations/007_session_replay_metadata.sql +10 -0
  110. package/src/migrations/008_session_replay_storage_bytes.sql +1 -0
  111. package/src/migrations/009_projects_and_keys.sql +22 -0
  112. package/src/migrations/010_signal_project_id.sql +15 -0
  113. package/src/migrations/011_default_project_seed.sql +3 -0
  114. package/src/migrations/012_alert_rules.sql +17 -0
  115. package/src/migrations/013_alert_evaluations.sql +13 -0
  116. package/src/migrations/014_alert_state.sql +9 -0
  117. package/src/migrations/015_metrics.sql +58 -0
  118. package/src/migrations/016_metrics_exp_histogram_summary.sql +5 -0
  119. package/src/migrations/017_span_dropped_counts.sql +11 -0
  120. package/src/migrations/018_log_flags.sql +8 -0
  121. package/src/migrations/019_ai_span_payloads.sql +30 -0
  122. package/src/migrations/020_ai_span_evaluations.sql +33 -0
  123. package/src/migrations/021_ai_span_session.sql +13 -0
  124. package/src/migrations/022_span_log_session_id.sql +13 -0
  125. package/src/migrations/023_service_map_indexes.sql +32 -0
  126. package/src/migrations/024_analysis_results.sql +49 -0
  127. package/src/migrations/025_stage6_autopinning_alerts.sql +38 -0
  128. package/src/migrations/026_obs_dashboard_project_seed.sql +18 -0
  129. package/src/migrations/027_identity_propagation.sql +50 -0
  130. package/src/migrations/028_profile_blobs.sql +57 -0
  131. package/src/migrations/029_telemetry_sdk_name.sql +20 -0
  132. package/src/migrations/030_analysis_claim.sql +18 -0
  133. package/src/migrations/031_agent_action_graph.sql +154 -0
  134. package/src/migrations/032_payload_capture_flags.sql +8 -0
  135. package/src/migrations/033_eval_cases.sql +52 -0
  136. package/src/migrations/034_eval_case_results.sql +23 -0
  137. package/src/migrations/035_metric_exemplars.sql +33 -0
  138. package/src/migrations/036_trace_instrumentation_gaps.sql +19 -0
  139. package/src/migrations/037_eval_runs.sql +37 -0
  140. package/src/migrations/038_tool_call_evidence.sql +11 -0
  141. package/src/migrations/039_drop_trace_instrumentation_gaps.sql +11 -0
  142. package/src/migrations/040_evidence_retrieval_refs.sql +50 -0
  143. package/src/migrations-postgres/001_telemetry_spans.sql +33 -0
  144. package/src/migrations-postgres/002_usage_events.sql +24 -0
  145. package/src/migrations-postgres/003_usage_analytics_columns.sql +13 -0
  146. package/src/migrations-postgres/004_logs.sql +19 -0
  147. package/src/migrations-postgres/005_ai_calls.sql +25 -0
  148. package/src/migrations-postgres/006_user_profiles.sql +11 -0
  149. package/src/migrations-postgres/007_session_replay_metadata.sql +10 -0
  150. package/src/migrations-postgres/008_session_replay_storage_bytes.sql +2 -0
  151. package/src/migrations-postgres/009_projects_and_keys.sql +25 -0
  152. package/src/migrations-postgres/010_signal_project_id.sql +18 -0
  153. package/src/migrations-postgres/011_default_project_seed.sql +5 -0
  154. package/src/migrations-postgres/012_alert_rules.sql +17 -0
  155. package/src/migrations-postgres/013_alert_evaluations.sql +13 -0
  156. package/src/migrations-postgres/014_alert_state.sql +9 -0
  157. package/src/migrations-postgres/015_metrics.sql +47 -0
  158. package/src/migrations-postgres/016_metrics_exp_histogram_summary.sql +1 -0
  159. package/src/migrations-postgres/017_span_dropped_counts.sql +4 -0
  160. package/src/migrations-postgres/018_log_flags.sql +2 -0
  161. package/src/migrations-postgres/019_ai_span_payloads.sql +18 -0
  162. package/src/migrations-postgres/020_ai_span_evaluations.sql +21 -0
  163. package/src/migrations-postgres/021_ai_span_session.sql +7 -0
  164. package/src/migrations-postgres/022_span_log_session_id.sql +7 -0
  165. package/src/migrations-postgres/023_service_map_indexes.sql +9 -0
  166. package/src/migrations-postgres/024_analysis_results.sql +41 -0
  167. package/src/migrations-postgres/025_stage6_autopinning_alerts.sql +17 -0
  168. package/src/migrations-postgres/026_obs_dashboard_project_seed.sql +14 -0
  169. package/src/migrations-postgres/027_identity_propagation.sql +27 -0
  170. package/src/migrations-postgres/028_profile_blobs.sql +48 -0
  171. package/src/migrations-postgres/029_telemetry_sdk_name.sql +5 -0
  172. package/src/migrations-postgres/030_analysis_claim.sql +5 -0
  173. package/src/migrations-postgres/031_agent_action_graph.sql +190 -0
  174. package/src/migrations-postgres/032_payload_capture_flags.sql +8 -0
  175. package/src/migrations-postgres/033_eval_cases.sql +55 -0
  176. package/src/migrations-postgres/034_eval_case_results.sql +26 -0
  177. package/src/migrations-postgres/035_metric_exemplars.sql +31 -0
  178. package/src/migrations-postgres/036_trace_instrumentation_gaps.sql +19 -0
  179. package/src/migrations-postgres/037_eval_runs.sql +40 -0
  180. package/src/migrations-postgres/038_tool_call_evidence.sql +11 -0
  181. package/src/migrations-postgres/039_drop_trace_instrumentation_gaps.sql +11 -0
  182. package/src/migrations-postgres/040_evidence_retrieval_refs.sql +47 -0
  183. package/src/migrations-postgres/README.md +40 -0
  184. package/src/otlp/acceptance.test.ts +373 -0
  185. package/src/otlp/decode/body.ts +127 -0
  186. package/src/otlp/decode/logs.ts +96 -0
  187. package/src/otlp/decode/metrics.ts +402 -0
  188. package/src/otlp/decode/traces.ts +92 -0
  189. package/src/otlp/decode/values.ts +150 -0
  190. package/src/otlp/decode.test.ts +800 -0
  191. package/src/otlp/decode.ts +11 -0
  192. package/src/otlp/gen/opentelemetry/proto/collector/logs/v1/logs_service_pb.ts +132 -0
  193. package/src/otlp/gen/opentelemetry/proto/collector/metrics/v1/metrics_service_pb.ts +158 -0
  194. package/src/otlp/gen/opentelemetry/proto/collector/trace/v1/trace_service_pb.ts +158 -0
  195. package/src/otlp/gen/opentelemetry/proto/common/v1/common_pb.ts +289 -0
  196. package/src/otlp/gen/opentelemetry/proto/logs/v1/logs_pb.ts +397 -0
  197. package/src/otlp/gen/opentelemetry/proto/metrics/v1/metrics_pb.ts +1329 -0
  198. package/src/otlp/gen/opentelemetry/proto/resource/v1/resource_pb.ts +86 -0
  199. package/src/otlp/gen/opentelemetry/proto/trace/v1/trace_pb.ts +710 -0
  200. package/src/otlp/response.test.ts +158 -0
  201. package/src/otlp/response.ts +129 -0
  202. package/src/plugins/_context.ts +15 -0
  203. package/src/plugins/action-graph-processor/enrichers.ts +45 -0
  204. package/src/plugins/action-graph-processor/redaction.ts +84 -0
  205. package/src/plugins/action-graph-processor.test.ts +1023 -0
  206. package/src/plugins/action-graph-processor.ts +1172 -0
  207. package/src/plugins/action-routes.test.ts +716 -0
  208. package/src/plugins/action-routes.ts +343 -0
  209. package/src/plugins/ai-receiver.ts +254 -0
  210. package/src/plugins/ai-span-payloads-processor.test.ts +90 -0
  211. package/src/plugins/ai-span-payloads-processor.ts +180 -0
  212. package/src/plugins/alerts-evaluator.test.ts +91 -0
  213. package/src/plugins/alerts-evaluator.ts +328 -0
  214. package/src/plugins/alerts-routes.ts +101 -0
  215. package/src/plugins/analyses-routes.ts +138 -0
  216. package/src/plugins/ask-routes.ts +182 -0
  217. package/src/plugins/bot-filter.ts +19 -0
  218. package/src/plugins/connected-routes/manifest.ts +531 -0
  219. package/src/plugins/connected-routes.test.ts +1791 -0
  220. package/src/plugins/connected-routes.ts +1103 -0
  221. package/src/plugins/dashboard-routes.ts +41 -0
  222. package/src/plugins/default-span-enrichment.ts +92 -0
  223. package/src/plugins/eval-cases-routes.test.ts +391 -0
  224. package/src/plugins/eval-cases-routes.ts +529 -0
  225. package/src/plugins/evidence-retrieval-routes.benchmark.test.ts +245 -0
  226. package/src/plugins/evidence-retrieval-routes.test.ts +932 -0
  227. package/src/plugins/evidence-retrieval-routes.ts +2179 -0
  228. package/src/plugins/gen-ai-normalizer.test.ts +680 -0
  229. package/src/plugins/gen-ai-normalizer.ts +302 -0
  230. package/src/plugins/identity-receiver.ts +96 -0
  231. package/src/plugins/issue-enrichment.ts +132 -0
  232. package/src/plugins/issue-insights.ts +81 -0
  233. package/src/plugins/logs-receiver.ts +160 -0
  234. package/src/plugins/metrics-receiver.ts +91 -0
  235. package/src/plugins/onboarding-routes.ts +54 -0
  236. package/src/plugins/otlp-receiver.ts +124 -0
  237. package/src/plugins/platform-routes.ts +165 -0
  238. package/src/plugins/profile-routes.ts +468 -0
  239. package/src/plugins/projects-routes.ts +92 -0
  240. package/src/plugins/query-routes.ts +220 -0
  241. package/src/plugins/redaction-processor.ts +132 -0
  242. package/src/plugins/replay-query-routes.test.ts +38 -0
  243. package/src/plugins/replay-query-routes.ts +199 -0
  244. package/src/plugins/replay-receiver.ts +81 -0
  245. package/src/plugins/tail-routes.test.ts +47 -0
  246. package/src/plugins/tail-routes.ts +42 -0
  247. package/src/plugins/timeline-routes.ts +244 -0
  248. package/src/plugins/ua-enrichment.ts +27 -0
  249. package/src/plugins/usage-normalization.ts +46 -0
  250. package/src/plugins/usage-privacy.ts +55 -0
  251. package/src/plugins/usage-query-routes.ts +102 -0
  252. package/src/plugins/usage-receiver.ts +129 -0
  253. package/src/plugins/users-query-routes.ts +78 -0
  254. package/src/plugins/utm-enrichment.ts +36 -0
@@ -0,0 +1,47 @@
1
+ CREATE TABLE IF NOT EXISTS metric_series (
2
+ id TEXT PRIMARY KEY,
3
+ project_id TEXT NOT NULL,
4
+ name TEXT NOT NULL,
5
+ description TEXT,
6
+ unit TEXT,
7
+ type TEXT NOT NULL,
8
+ is_monotonic INTEGER,
9
+ temporality INTEGER,
10
+ scope_name TEXT,
11
+ scope_version TEXT,
12
+ service_name TEXT,
13
+ resource_attrs_json JSONB,
14
+ attributes_json JSONB,
15
+ identity TEXT NOT NULL,
16
+ created_at TEXT NOT NULL,
17
+ UNIQUE(project_id, identity)
18
+ );
19
+
20
+ CREATE INDEX IF NOT EXISTS idx_metric_series_project_name
21
+ ON metric_series (project_id, name);
22
+
23
+ CREATE TABLE IF NOT EXISTS metric_point (
24
+ id TEXT PRIMARY KEY,
25
+ series_id TEXT NOT NULL,
26
+ project_id TEXT NOT NULL,
27
+ ts_ns TEXT NOT NULL,
28
+ start_ts_ns TEXT,
29
+ value DOUBLE PRECISION,
30
+ count BIGINT,
31
+ sum DOUBLE PRECISION,
32
+ min DOUBLE PRECISION,
33
+ max DOUBLE PRECISION,
34
+ bounds_json JSONB,
35
+ bucket_counts_json JSONB,
36
+ exemplars_json JSONB,
37
+ received_at TEXT NOT NULL,
38
+ expires_at TEXT NOT NULL,
39
+ FOREIGN KEY (series_id) REFERENCES metric_series(id)
40
+ );
41
+
42
+ CREATE INDEX IF NOT EXISTS idx_metric_point_series_ts
43
+ ON metric_point (series_id, ts_ns);
44
+ CREATE INDEX IF NOT EXISTS idx_metric_point_expires
45
+ ON metric_point (expires_at);
46
+ CREATE INDEX IF NOT EXISTS idx_metric_point_project_received
47
+ ON metric_point (project_id, received_at DESC);
@@ -0,0 +1 @@
1
+ ALTER TABLE metric_point ADD COLUMN IF NOT EXISTS extra_json JSONB;
@@ -0,0 +1,4 @@
1
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS trace_state TEXT;
2
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS dropped_attributes_count INTEGER NOT NULL DEFAULT 0;
3
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS dropped_events_count INTEGER NOT NULL DEFAULT 0;
4
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS dropped_links_count INTEGER NOT NULL DEFAULT 0;
@@ -0,0 +1,2 @@
1
+ ALTER TABLE logs ADD COLUMN IF NOT EXISTS flags INTEGER NOT NULL DEFAULT 0;
2
+ ALTER TABLE logs ADD COLUMN IF NOT EXISTS dropped_attributes_count INTEGER NOT NULL DEFAULT 0;
@@ -0,0 +1,18 @@
1
+ CREATE TABLE IF NOT EXISTS ai_span_payloads (
2
+ project_id TEXT NOT NULL,
3
+ trace_id TEXT NOT NULL,
4
+ span_id TEXT NOT NULL,
5
+ span_kind TEXT NOT NULL,
6
+ input_json JSONB,
7
+ output_json JSONB,
8
+ received_at TEXT NOT NULL,
9
+ expires_at TEXT NOT NULL,
10
+ PRIMARY KEY (trace_id, span_id)
11
+ );
12
+
13
+ CREATE INDEX IF NOT EXISTS idx_ai_payloads_received
14
+ ON ai_span_payloads (received_at DESC);
15
+ CREATE INDEX IF NOT EXISTS idx_ai_payloads_project
16
+ ON ai_span_payloads (project_id, received_at DESC);
17
+ CREATE INDEX IF NOT EXISTS idx_ai_payloads_kind
18
+ ON ai_span_payloads (project_id, span_kind, received_at DESC);
@@ -0,0 +1,21 @@
1
+ CREATE TABLE IF NOT EXISTS ai_span_evaluations (
2
+ evaluation_id TEXT PRIMARY KEY,
3
+ project_id TEXT NOT NULL,
4
+ trace_id TEXT NOT NULL,
5
+ span_id TEXT NOT NULL,
6
+ name TEXT NOT NULL,
7
+ score DOUBLE PRECISION,
8
+ label TEXT,
9
+ explanation TEXT,
10
+ source TEXT NOT NULL,
11
+ metadata_json JSONB,
12
+ created_at TEXT NOT NULL,
13
+ expires_at TEXT NOT NULL
14
+ );
15
+
16
+ CREATE INDEX IF NOT EXISTS idx_ai_evals_span
17
+ ON ai_span_evaluations (trace_id, span_id);
18
+ CREATE INDEX IF NOT EXISTS idx_ai_evals_project_created
19
+ ON ai_span_evaluations (project_id, created_at DESC);
20
+ CREATE INDEX IF NOT EXISTS idx_ai_evals_project_name
21
+ ON ai_span_evaluations (project_id, name, created_at DESC);
@@ -0,0 +1,7 @@
1
+ ALTER TABLE ai_span_payloads ADD COLUMN IF NOT EXISTS session_id TEXT;
2
+ ALTER TABLE ai_span_payloads ADD COLUMN IF NOT EXISTS user_id TEXT;
3
+
4
+ CREATE INDEX IF NOT EXISTS idx_ai_payloads_session
5
+ ON ai_span_payloads (project_id, session_id, received_at DESC);
6
+ CREATE INDEX IF NOT EXISTS idx_ai_payloads_user
7
+ ON ai_span_payloads (project_id, user_id, received_at DESC);
@@ -0,0 +1,7 @@
1
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS session_id TEXT;
2
+ ALTER TABLE logs ADD COLUMN IF NOT EXISTS session_id TEXT;
3
+
4
+ CREATE INDEX IF NOT EXISTS idx_spans_session
5
+ ON telemetry_spans (project_id, session_id, received_at DESC);
6
+ CREATE INDEX IF NOT EXISTS idx_logs_session
7
+ ON logs (project_id, session_id, received_at DESC);
@@ -0,0 +1,9 @@
1
+ CREATE INDEX IF NOT EXISTS idx_spans_project_received
2
+ ON telemetry_spans (project_id, received_at DESC);
3
+
4
+ CREATE INDEX IF NOT EXISTS idx_spans_with_links
5
+ ON telemetry_spans (project_id, received_at DESC)
6
+ WHERE links_json IS NOT NULL AND links_json <> '[]'::jsonb;
7
+
8
+ CREATE INDEX IF NOT EXISTS idx_spans_project_service_received
9
+ ON telemetry_spans (project_id, service_name, received_at DESC);
@@ -0,0 +1,41 @@
1
+ CREATE TABLE IF NOT EXISTS analysis_definitions (
2
+ project_id TEXT NOT NULL,
3
+ id TEXT NOT NULL,
4
+ title TEXT NOT NULL,
5
+ "group" TEXT NOT NULL,
6
+ source TEXT NOT NULL,
7
+ view TEXT NOT NULL,
8
+ refresh_seconds INTEGER,
9
+ sql TEXT,
10
+ scope_json JSONB,
11
+ created_at TEXT NOT NULL,
12
+ updated_at TEXT NOT NULL,
13
+ last_run_at TEXT,
14
+ PRIMARY KEY (project_id, id)
15
+ );
16
+
17
+ CREATE INDEX IF NOT EXISTS idx_analysis_definitions_group
18
+ ON analysis_definitions (project_id, "group", id);
19
+
20
+ CREATE TABLE IF NOT EXISTS analysis_results (
21
+ id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
22
+ project_id TEXT NOT NULL,
23
+ analysis_id TEXT NOT NULL,
24
+ generated_at BIGINT NOT NULL,
25
+ params_hash TEXT,
26
+ status TEXT NOT NULL,
27
+ primary_value DOUBLE PRECISION,
28
+ baseline_value DOUBLE PRECISION,
29
+ delta_pct DOUBLE PRECISION,
30
+ payload_json JSONB NOT NULL,
31
+ narrative TEXT,
32
+ narrative_signature TEXT,
33
+ duration_ms INTEGER NOT NULL,
34
+ expires_at BIGINT NOT NULL
35
+ );
36
+
37
+ CREATE INDEX IF NOT EXISTS idx_analysis_results_latest
38
+ ON analysis_results (project_id, analysis_id, generated_at DESC);
39
+
40
+ CREATE INDEX IF NOT EXISTS idx_analysis_results_expires
41
+ ON analysis_results (expires_at);
@@ -0,0 +1,17 @@
1
+ CREATE TABLE IF NOT EXISTS ask_evidence_events (
2
+ id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
3
+ project_id TEXT NOT NULL,
4
+ analysis_id TEXT NOT NULL,
5
+ asked_at BIGINT NOT NULL
6
+ );
7
+
8
+ CREATE INDEX IF NOT EXISTS idx_ask_evidence_events_recent
9
+ ON ask_evidence_events (project_id, asked_at DESC);
10
+
11
+ CREATE INDEX IF NOT EXISTS idx_ask_evidence_events_analysis
12
+ ON ask_evidence_events (project_id, analysis_id, asked_at DESC);
13
+
14
+ ALTER TABLE alert_rules ADD COLUMN IF NOT EXISTS analysis_id TEXT;
15
+
16
+ CREATE INDEX IF NOT EXISTS idx_alert_rules_analysis
17
+ ON alert_rules (project_id, analysis_id);
@@ -0,0 +1,14 @@
1
+ INSERT INTO projects (id, name, slug, created_at)
2
+ VALUES ('obs-dashboard', 'Obs Dashboard', 'obs-dashboard', now()::text)
3
+ ON CONFLICT (id) DO NOTHING;
4
+
5
+ INSERT INTO ingest_keys (id, project_id, key_hash, key_prefix, name, created_at)
6
+ VALUES (
7
+ 'obs-dashboard-bootstrap',
8
+ 'obs-dashboard',
9
+ decode('6aa18dc1261b312e98b236d5a7dae698d1a90ecbe33d8024744063a066a35b9b', 'hex'),
10
+ 'obs_dashboard_65',
11
+ 'bootstrap',
12
+ now()::text
13
+ )
14
+ ON CONFLICT (id) DO NOTHING;
@@ -0,0 +1,27 @@
1
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS interaction_id TEXT;
2
+ ALTER TABLE logs ADD COLUMN IF NOT EXISTS interaction_id TEXT;
3
+ ALTER TABLE usage_events ADD COLUMN IF NOT EXISTS interaction_id TEXT;
4
+ ALTER TABLE ai_calls ADD COLUMN IF NOT EXISTS interaction_id TEXT;
5
+ ALTER TABLE ai_span_payloads ADD COLUMN IF NOT EXISTS interaction_id TEXT;
6
+
7
+ ALTER TABLE ai_calls ADD COLUMN IF NOT EXISTS session_id TEXT;
8
+
9
+ CREATE INDEX IF NOT EXISTS idx_spans_interaction
10
+ ON telemetry_spans (project_id, interaction_id, received_at DESC)
11
+ WHERE interaction_id IS NOT NULL;
12
+
13
+ CREATE INDEX IF NOT EXISTS idx_logs_interaction
14
+ ON logs (project_id, interaction_id, received_at DESC)
15
+ WHERE interaction_id IS NOT NULL;
16
+
17
+ CREATE INDEX IF NOT EXISTS idx_usage_interaction
18
+ ON usage_events (project_id, interaction_id, received_at DESC)
19
+ WHERE interaction_id IS NOT NULL;
20
+
21
+ CREATE INDEX IF NOT EXISTS idx_ai_calls_interaction
22
+ ON ai_calls (project_id, interaction_id, received_at DESC)
23
+ WHERE interaction_id IS NOT NULL;
24
+
25
+ CREATE INDEX IF NOT EXISTS idx_ai_calls_session
26
+ ON ai_calls (project_id, session_id, received_at DESC)
27
+ WHERE session_id IS NOT NULL;
@@ -0,0 +1,48 @@
1
+ -- RFC 0007 — pprof profiling receiver storage.
2
+ --
3
+ -- Postgres translation of the D1 profile metadata/index tables. Blob bytes live
4
+ -- in S3-compatible storage; these tables make profiles discoverable by id,
5
+ -- service, and trace.
6
+
7
+ CREATE TABLE IF NOT EXISTS profile_blobs (
8
+ id TEXT PRIMARY KEY,
9
+ project_id TEXT NOT NULL,
10
+ service_name TEXT,
11
+ profile_type TEXT NOT NULL,
12
+ start_ts TEXT NOT NULL,
13
+ end_ts TEXT NOT NULL,
14
+ duration_ms BIGINT NOT NULL,
15
+ blob_size_bytes BIGINT NOT NULL,
16
+ blob_url TEXT NOT NULL,
17
+ sample_count BIGINT,
18
+ agent TEXT,
19
+ resource_attrs_json JSONB,
20
+ received_at TEXT NOT NULL,
21
+ expires_at TEXT NOT NULL
22
+ );
23
+
24
+ CREATE INDEX IF NOT EXISTS idx_profile_blobs_service_ts
25
+ ON profile_blobs (project_id, service_name, end_ts DESC);
26
+
27
+ CREATE INDEX IF NOT EXISTS idx_profile_blobs_expires
28
+ ON profile_blobs (expires_at);
29
+
30
+ -- Postgres-only GIN index so the dashboard read paths can query against
31
+ -- resource attributes (service.version, deployment.environment, etc.).
32
+ -- Matches the JSONB+GIN pattern from 001 and 031.
33
+ CREATE INDEX IF NOT EXISTS idx_profile_blobs_resource_attrs_gin
34
+ ON profile_blobs USING GIN (resource_attrs_json);
35
+
36
+ CREATE TABLE IF NOT EXISTS profile_trace_index (
37
+ profile_id TEXT NOT NULL,
38
+ trace_id TEXT NOT NULL,
39
+ project_id TEXT NOT NULL,
40
+ PRIMARY KEY (profile_id, trace_id),
41
+ FOREIGN KEY (profile_id) REFERENCES profile_blobs(id) ON DELETE CASCADE
42
+ );
43
+
44
+ CREATE INDEX IF NOT EXISTS idx_profile_trace_index_trace
45
+ ON profile_trace_index (project_id, trace_id);
46
+
47
+ CREATE INDEX IF NOT EXISTS idx_profile_trace_index_profile
48
+ ON profile_trace_index (profile_id);
@@ -0,0 +1,5 @@
1
+ ALTER TABLE telemetry_spans ADD COLUMN IF NOT EXISTS telemetry_sdk_name TEXT;
2
+
3
+ CREATE INDEX IF NOT EXISTS idx_spans_sdk_name
4
+ ON telemetry_spans (project_id, telemetry_sdk_name, received_at DESC)
5
+ WHERE telemetry_sdk_name IS NOT NULL;
@@ -0,0 +1,5 @@
1
+ ALTER TABLE analysis_definitions ADD COLUMN IF NOT EXISTS last_started_at TEXT;
2
+
3
+ CREATE INDEX IF NOT EXISTS idx_analysis_definitions_started
4
+ ON analysis_definitions (project_id, last_started_at)
5
+ WHERE last_started_at IS NOT NULL;
@@ -0,0 +1,190 @@
1
+ -- RFC 0010: Agent Action Graph Spine Schema (Phase 1)
2
+ --
3
+ -- Creates the action spine and detail leaf tables, and extends existing tables
4
+ -- to support higher-level causal action tracing for agentic systems.
5
+
6
+ -- 1. General Action Spine
7
+ CREATE TABLE IF NOT EXISTS actions (
8
+ id TEXT PRIMARY KEY, -- Unique ULID / ID for this action
9
+ project_id TEXT NOT NULL, -- Project scope
10
+ root_action_id TEXT NOT NULL, -- ULID of the root causal action
11
+ caused_by_action_id TEXT, -- ULID of the parent causal action
12
+ actor_type TEXT NOT NULL, -- human, agent, service, workflow, system
13
+ actor_id TEXT, -- ID of the actor initiating this action
14
+ action_kind TEXT NOT NULL, -- agent.run, agent.step, llm.call, tool.call, retrieval, eval, etc.
15
+ name TEXT, -- Human readable name
16
+ status TEXT NOT NULL DEFAULT 'ok', -- ok, error
17
+ started_at TEXT NOT NULL, -- ISO8601 timestamp
18
+ ended_at TEXT, -- ISO8601 timestamp
19
+ duration_ms INTEGER, -- Execution duration
20
+ trace_id TEXT, -- Optional linked OTel trace ID
21
+ span_id TEXT, -- Optional linked OTel span ID
22
+ session_id TEXT, -- Optional browser/user session
23
+ interaction_id TEXT, -- Optional click-scoped correlation key
24
+ user_id TEXT, -- Optional user ID
25
+ agent_run_id TEXT, -- Optional linked Agent Run ID
26
+ step_id TEXT, -- Optional linked Step ID
27
+ tool_call_id TEXT, -- Optional linked Tool Call ID
28
+ prompt_version TEXT, -- Denormalized prompt version
29
+ model_name TEXT, -- Denormalized LLM model name
30
+ provider TEXT, -- Denormalized LLM provider name
31
+ total_cost_usd DOUBLE PRECISION, -- Denormalized token/tool cost
32
+ attrs_json JSONB -- Arbitrary JSON key-value store for plugin/custom data
33
+ );
34
+
35
+ -- Indices for fast spine traversal
36
+ CREATE INDEX IF NOT EXISTS idx_actions_project_root
37
+ ON actions (project_id, root_action_id, started_at);
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_actions_project_actor
40
+ ON actions (project_id, actor_type, actor_id, started_at DESC);
41
+
42
+ CREATE INDEX IF NOT EXISTS idx_actions_project_trace
43
+ ON actions (project_id, trace_id)
44
+ WHERE trace_id IS NOT NULL;
45
+
46
+ CREATE INDEX IF NOT EXISTS idx_actions_project_interaction
47
+ ON actions (project_id, interaction_id)
48
+ WHERE interaction_id IS NOT NULL;
49
+
50
+ CREATE INDEX IF NOT EXISTS idx_actions_project_agent_run
51
+ ON actions (project_id, agent_run_id, started_at)
52
+ WHERE agent_run_id IS NOT NULL;
53
+
54
+ -- Postgres-only GIN index
55
+ CREATE INDEX IF NOT EXISTS idx_actions_attrs_gin
56
+ ON actions USING GIN (attrs_json);
57
+
58
+
59
+ -- 2. Detail Leaf: Agent Runs
60
+ CREATE TABLE IF NOT EXISTS agent_runs (
61
+ id TEXT PRIMARY KEY, -- Matches actions.id for the run's root action
62
+ project_id TEXT NOT NULL,
63
+ agent_id TEXT NOT NULL, -- Stable identifier of the agent template/codebase
64
+ agent_name TEXT NOT NULL, -- Human-readable name of the agent
65
+ agent_version TEXT NOT NULL, -- Version of agent configuration/strategy
66
+ goal TEXT, -- High-level prompt or goal of the run
67
+ outcome TEXT, -- Final answer, result summary, or output
68
+ autonomy_level TEXT NOT NULL, -- read_only, suggested_action, human_approved_write, autonomous_write, blocked_by_policy
69
+ status TEXT NOT NULL DEFAULT 'running', -- running, success, failed
70
+ error_message TEXT, -- Optional error string
71
+ total_cost_usd DOUBLE PRECISION DEFAULT 0.0,
72
+ total_duration_ms INTEGER,
73
+ metadata_json JSONB -- Opt-in debug metadata
74
+ );
75
+
76
+ CREATE INDEX IF NOT EXISTS idx_agent_runs_project_agent
77
+ ON agent_runs (project_id, agent_id, status);
78
+
79
+ CREATE INDEX IF NOT EXISTS idx_agent_runs_metadata_gin
80
+ ON agent_runs USING GIN (metadata_json);
81
+
82
+
83
+ -- 3. Detail Leaf: Tool Calls
84
+ CREATE TABLE IF NOT EXISTS tool_calls (
85
+ id TEXT PRIMARY KEY, -- Unique identifier (often matches OTel span_id or actions.id)
86
+ action_id TEXT NOT NULL, -- Links back to actions.id
87
+ project_id TEXT NOT NULL,
88
+ tool_name TEXT NOT NULL, -- Named tool (e.g. sql_query, fetch_invoice)
89
+ args_hash TEXT NOT NULL, -- SHA256 of args for privacy-preserving cache key
90
+ result_hash TEXT NOT NULL, -- SHA256 of result for parity verification
91
+ error_type TEXT, -- Optional error classifier (e.g. timeout, auth)
92
+ side_effect INTEGER NOT NULL DEFAULT 0, -- Boolean (0/1): does this tool mutate state?
93
+ approval_state TEXT, -- suggested, human_approved, bypassed, blocked
94
+ args_redacted JSONB, -- Opt-in redacted parameters JSON
95
+ result_redacted JSONB -- Opt-in redacted result JSON
96
+ );
97
+
98
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_action
99
+ ON tool_calls (action_id);
100
+
101
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_name
102
+ ON tool_calls (project_id, tool_name);
103
+
104
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_args_redacted_gin
105
+ ON tool_calls USING GIN (args_redacted);
106
+
107
+ CREATE INDEX IF NOT EXISTS idx_tool_calls_result_redacted_gin
108
+ ON tool_calls USING GIN (result_redacted);
109
+
110
+
111
+ -- 4. Detail Leaf: Retrieval Events
112
+ CREATE TABLE IF NOT EXISTS retrieval_events (
113
+ id TEXT PRIMARY KEY,
114
+ action_id TEXT NOT NULL, -- Links back to actions.id
115
+ project_id TEXT NOT NULL,
116
+ retriever_name TEXT NOT NULL, -- Name of vector DB or retriever system
117
+ query_hash TEXT NOT NULL, -- SHA-256 of the retrieval query string
118
+ documents_json JSONB, -- Array of { docId, score, sourceId, snippet_preview }
119
+ total_results INTEGER NOT NULL DEFAULT 0,
120
+ max_relevance_score DOUBLE PRECISION,
121
+ duration_ms INTEGER
122
+ );
123
+
124
+ CREATE INDEX IF NOT EXISTS idx_retrieval_events_action
125
+ ON retrieval_events (action_id);
126
+
127
+ CREATE INDEX IF NOT EXISTS idx_retrieval_events_docs_gin
128
+ ON retrieval_events USING GIN (documents_json);
129
+
130
+
131
+ -- 5. Detail Leaf: Evaluation & Guardrail Results
132
+ CREATE TABLE IF NOT EXISTS eval_results (
133
+ id TEXT PRIMARY KEY,
134
+ action_id TEXT NOT NULL, -- Links back to actions.id
135
+ project_id TEXT NOT NULL,
136
+ evaluator_name TEXT NOT NULL, -- Name of the evaluator or guardrail (e.g. groundedness)
137
+ evaluator_version TEXT NOT NULL, -- Grader version
138
+ score DOUBLE PRECISION, -- Numeric metric between 0.0 and 1.0
139
+ passed INTEGER NOT NULL DEFAULT 1, -- Boolean (0/1) for binary policy gates
140
+ reasoning TEXT, -- Explanation or chain-of-thought of the grader
141
+ rubric_json JSONB -- Optional grader schema or rubric details
142
+ );
143
+
144
+ CREATE INDEX IF NOT EXISTS idx_eval_results_action
145
+ ON eval_results (action_id);
146
+
147
+ CREATE INDEX IF NOT EXISTS idx_eval_results_rubric_gin
148
+ ON eval_results USING GIN (rubric_json);
149
+
150
+
151
+ -- 6. Detail Leaf: Generated Artifacts
152
+ CREATE TABLE IF NOT EXISTS artifacts (
153
+ id TEXT PRIMARY KEY,
154
+ action_id TEXT NOT NULL, -- Links back to actions.id
155
+ project_id TEXT NOT NULL,
156
+ artifact_name TEXT NOT NULL, -- e.g. "invoice-pdf"
157
+ artifact_type TEXT NOT NULL, -- file, patch, text, message, data
158
+ storage_ref TEXT, -- S3 / Blob reference
159
+ size_bytes INTEGER,
160
+ sha256_hash TEXT,
161
+ content_preview TEXT -- Redacted preview or summary
162
+ );
163
+
164
+ CREATE INDEX IF NOT EXISTS idx_artifacts_action
165
+ ON artifacts (action_id);
166
+
167
+
168
+ -- 7. Extend Existing AI Span Payloads Table
169
+ --
170
+ -- NOTE: `ai_span_payloads` is created by migration 019, which has not yet been
171
+ -- translated to Postgres (migrations 011-030 land alongside the first hosted-
172
+ -- Postgres deployment; see migrations-postgres/README.md). Until 019 exists in
173
+ -- this directory, a bare `ALTER TABLE ai_span_payloads` would abort the whole
174
+ -- run with `relation "ai_span_payloads" does not exist`.
175
+ --
176
+ -- We guard the extension on the table actually existing. On a fresh DB without
177
+ -- 019 the block is a no-op; once 019 is translated it sorts before 031, so the
178
+ -- column + index are added as intended. Both inner statements are idempotent
179
+ -- (`IF NOT EXISTS`), so re-running after 019 lands is safe.
180
+ DO $$
181
+ BEGIN
182
+ IF to_regclass('ai_span_payloads') IS NOT NULL THEN
183
+ ALTER TABLE ai_span_payloads ADD COLUMN IF NOT EXISTS action_id TEXT;
184
+
185
+ CREATE INDEX IF NOT EXISTS idx_ai_payloads_action
186
+ ON ai_span_payloads (project_id, action_id)
187
+ WHERE action_id IS NOT NULL;
188
+ END IF;
189
+ END
190
+ $$;
@@ -0,0 +1,8 @@
1
+ ALTER TABLE projects
2
+ ADD COLUMN IF NOT EXISTS payload_capture_enabled BOOLEAN NOT NULL DEFAULT FALSE;
3
+
4
+ ALTER TABLE ai_span_payloads
5
+ ADD COLUMN IF NOT EXISTS input_hash TEXT;
6
+
7
+ ALTER TABLE ai_span_payloads
8
+ ADD COLUMN IF NOT EXISTS output_hash TEXT;
@@ -0,0 +1,55 @@
1
+ -- RFC 0010 Phase 7: production-to-eval case persistence.
2
+ --
3
+ -- Eval cases are reusable fixtures captured from production telemetry. They
4
+ -- retain stable source links back to the production entity that created the
5
+ -- case while keeping prompts/payloads in explicitly redacted JSON fields.
6
+
7
+ CREATE TABLE IF NOT EXISTS eval_cases (
8
+ id TEXT PRIMARY KEY,
9
+ project_id TEXT NOT NULL,
10
+ source_entity_type TEXT NOT NULL,
11
+ source_entity_id TEXT NOT NULL,
12
+ source_agent_run_id TEXT,
13
+ source_action_id TEXT,
14
+ source_ai_call_id TEXT,
15
+ source_tool_call_id TEXT,
16
+ source_trace_id TEXT,
17
+ source_span_id TEXT,
18
+ name TEXT NOT NULL,
19
+ expected_outcome TEXT,
20
+ rubric_json JSONB,
21
+ redacted_prompt_json JSONB,
22
+ reference_payload_json JSONB,
23
+ metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb,
24
+ created_at TEXT NOT NULL,
25
+ updated_at TEXT NOT NULL
26
+ );
27
+
28
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_project_created
29
+ ON eval_cases (project_id, created_at DESC);
30
+
31
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_project_source
32
+ ON eval_cases (project_id, source_entity_type, source_entity_id, created_at DESC);
33
+
34
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_agent_run
35
+ ON eval_cases (project_id, source_agent_run_id)
36
+ WHERE source_agent_run_id IS NOT NULL;
37
+
38
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_action
39
+ ON eval_cases (project_id, source_action_id)
40
+ WHERE source_action_id IS NOT NULL;
41
+
42
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_ai_call
43
+ ON eval_cases (project_id, source_ai_call_id)
44
+ WHERE source_ai_call_id IS NOT NULL;
45
+
46
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_tool_call
47
+ ON eval_cases (project_id, source_tool_call_id)
48
+ WHERE source_tool_call_id IS NOT NULL;
49
+
50
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_trace
51
+ ON eval_cases (project_id, source_trace_id)
52
+ WHERE source_trace_id IS NOT NULL;
53
+
54
+ CREATE INDEX IF NOT EXISTS idx_eval_cases_metadata_gin
55
+ ON eval_cases USING GIN (metadata_json);
@@ -0,0 +1,26 @@
1
+ -- RFC 0010 Phase 7: reusable eval-case run results.
2
+ --
3
+ -- Results are produced by offline or CI evaluators against a saved production
4
+ -- eval case. They intentionally store compact comparison metadata rather than
5
+ -- raw prompts or completions.
6
+
7
+ CREATE TABLE IF NOT EXISTS eval_case_results (
8
+ id TEXT PRIMARY KEY,
9
+ project_id TEXT NOT NULL,
10
+ eval_case_id TEXT NOT NULL,
11
+ run_id TEXT NOT NULL,
12
+ passed INTEGER NOT NULL,
13
+ score REAL,
14
+ actual_outcome TEXT,
15
+ details_json JSONB,
16
+ created_at TEXT NOT NULL
17
+ );
18
+
19
+ CREATE INDEX IF NOT EXISTS idx_eval_case_results_case_created
20
+ ON eval_case_results (project_id, eval_case_id, created_at DESC);
21
+
22
+ CREATE INDEX IF NOT EXISTS idx_eval_case_results_run
23
+ ON eval_case_results (project_id, run_id);
24
+
25
+ CREATE INDEX IF NOT EXISTS idx_eval_case_results_details_gin
26
+ ON eval_case_results USING GIN (details_json);
@@ -0,0 +1,31 @@
1
+ -- Reverse index for OTLP metric exemplars.
2
+ --
3
+ -- metric_point.exemplars_json preserves the raw exemplar payload on the point,
4
+ -- but investigation flows need trace/span lookup without scanning JSON blobs.
5
+ -- This table turns exemplars into first-class correlation edges.
6
+
7
+ CREATE TABLE IF NOT EXISTS metric_exemplars (
8
+ id TEXT PRIMARY KEY,
9
+ point_id TEXT NOT NULL REFERENCES metric_point(id),
10
+ series_id TEXT NOT NULL REFERENCES metric_series(id),
11
+ project_id TEXT NOT NULL,
12
+ metric_name TEXT NOT NULL,
13
+ service_name TEXT,
14
+ trace_id TEXT,
15
+ span_id TEXT,
16
+ ts_ns TEXT NOT NULL,
17
+ value DOUBLE PRECISION NOT NULL,
18
+ received_at TIMESTAMPTZ NOT NULL,
19
+ expires_at TIMESTAMPTZ NOT NULL
20
+ );
21
+
22
+ CREATE INDEX IF NOT EXISTS idx_metric_exemplars_project_trace
23
+ ON metric_exemplars (project_id, trace_id, ts_ns)
24
+ WHERE trace_id IS NOT NULL;
25
+
26
+ CREATE INDEX IF NOT EXISTS idx_metric_exemplars_project_span
27
+ ON metric_exemplars (project_id, trace_id, span_id, ts_ns)
28
+ WHERE trace_id IS NOT NULL AND span_id IS NOT NULL;
29
+
30
+ CREATE INDEX IF NOT EXISTS idx_metric_exemplars_expires
31
+ ON metric_exemplars (expires_at);
@@ -0,0 +1,19 @@
1
+ -- Postgres migration 036_trace_instrumentation_gaps.sql
2
+ -- Computes and persists uninstrumented trace gaps during span ingestion.
3
+
4
+ CREATE TABLE IF NOT EXISTS trace_instrumentation_gaps (
5
+ trace_id TEXT NOT NULL,
6
+ parent_span_id TEXT NOT NULL,
7
+ parent_service_name TEXT NOT NULL,
8
+ parent_span_name TEXT NOT NULL,
9
+ offset_ms INTEGER NOT NULL,
10
+ duration_ms INTEGER NOT NULL,
11
+ ratio_of_parent REAL NOT NULL,
12
+ child_span_count INTEGER NOT NULL,
13
+ async_parent INTEGER NOT NULL, -- 0/1 boolean
14
+ recommendation TEXT NOT NULL,
15
+ PRIMARY KEY (trace_id, parent_span_id)
16
+ );
17
+
18
+ CREATE INDEX IF NOT EXISTS idx_trace_gaps_duration
19
+ ON trace_instrumentation_gaps (duration_ms DESC);
@@ -0,0 +1,40 @@
1
+ -- RFC 0010 Phase 7: durable eval runner records.
2
+ --
3
+ -- Eval runs group one or more eval case results under a candidate agent,
4
+ -- prompt, and model configuration so production behavior can be compared with
5
+ -- attempted fixes across repeatable runs.
6
+
7
+ CREATE TABLE IF NOT EXISTS eval_runs (
8
+ id TEXT PRIMARY KEY,
9
+ project_id TEXT NOT NULL,
10
+ eval_case_id TEXT,
11
+ candidate_agent_id TEXT,
12
+ candidate_agent_version TEXT,
13
+ candidate_prompt_id TEXT,
14
+ candidate_prompt_version TEXT,
15
+ candidate_model_provider TEXT,
16
+ candidate_model TEXT,
17
+ candidate_model_version TEXT,
18
+ status TEXT NOT NULL,
19
+ started_at TEXT,
20
+ ended_at TEXT,
21
+ total_count INTEGER NOT NULL DEFAULT 0,
22
+ pass_count INTEGER NOT NULL DEFAULT 0,
23
+ fail_count INTEGER NOT NULL DEFAULT 0,
24
+ average_score REAL,
25
+ metadata_json JSONB NOT NULL DEFAULT '{}'::jsonb,
26
+ created_at TEXT NOT NULL
27
+ );
28
+
29
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_project_created
30
+ ON eval_runs (project_id, created_at DESC);
31
+
32
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_case_created
33
+ ON eval_runs (project_id, eval_case_id, created_at DESC)
34
+ WHERE eval_case_id IS NOT NULL;
35
+
36
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_project_status_created
37
+ ON eval_runs (project_id, status, created_at DESC);
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_eval_runs_metadata_gin
40
+ ON eval_runs USING GIN (metadata_json);