Commit fe1d8a1
feat: [AI-5975] add sql_quality telemetry for issue prevention metrics (#446)
* feat: [AI-5975] add `sql_quality` telemetry for issue prevention metrics
Add a new `sql_quality` telemetry event that fires whenever tools
successfully detect SQL issues — turning findings into measurable
"issues prevented" data in App Insights.
Architecture:
- New `sql_quality` event type in `Telemetry.Event` with `finding_count`,
`by_severity`, `by_category`, `has_schema`, `dialect`, `duration_ms`
- New `Telemetry.Finding` interface and `aggregateFindings()` helper
- Centralized emission in `tool.ts` — checks `metadata.findings` array
after any tool completes, aggregates counts, emits event
- Tools populate `metadata.findings` with `{category, severity}` pairs:
- `sql_analyze`: issue type + severity from lint/semantic/safety analysis
- `altimate_core_validate`: classified validation errors (missing_table,
missing_column, syntax_error, type_mismatch)
- `altimate_core_semantics`: rule/type + severity from semantic checks
- `altimate_core_fix`: fix_applied / unfixable_error categories
- `altimate_core_correct`: correction_applied findings
- `altimate_core_equivalence`: equivalence_difference findings
PII-safe: only category names and severity levels flow to telemetry,
never SQL content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: [AI-5975] drop `by_severity` from `sql_quality` telemetry, address PR review
- Remove `severity` from `Finding` interface — only `category` matters
- Drop `by_severity` from `sql_quality` event type and `aggregateFindings`
- Gate `sql_quality` emission on `!isSoftFailure` to avoid double-counting
with `core_failure` events (Copilot review feedback)
- Simplify semantics tool: use fixed `"semantic_issue"` category instead of
dead `issue.rule ?? issue.type` fallback chain (CodeRabbit review feedback)
- Update test header to accurately describe what tests cover
- Fix sql_analyze test to use honest coarse categories (`"lint"`, `"safety"`)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: [AI-5975] drop `by_severity` from `sql_quality` telemetry, address PR review
- Remove `severity` from `Finding` interface — only `category` matters
- Drop `by_severity` from `sql_quality` event type and `aggregateFindings`
- Gate `sql_quality` emission on `!isSoftFailure` to avoid double-counting
with `core_failure` events (Copilot review feedback)
- Simplify semantics tool: use fixed `"semantic_issue"` category instead of
dead `issue.rule ?? issue.type` fallback chain (CodeRabbit review feedback)
- Update test header to accurately describe what tests cover
- Fix sql_analyze test to use honest coarse categories (`"lint"`, `"safety"`)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: [AI-5975] decouple `metadata.success` from domain outcomes in finding tools
Five tools were suppressing `sql_quality` telemetry because their
`metadata.success` tracked domain outcomes (SQL invalid, policy violated,
queries not equivalent) rather than engine execution success.
`tool.ts` gate: `!isSoftFailure && findings.length > 0`
- `isSoftFailure = metadata.success === false`
- Tools that found issues had `success: false` → findings suppressed
Fix: set `success: true` when the engine ran (even if it found problems).
Domain outcomes remain in dedicated fields (`valid`, `pass`, `equivalent`,
`fixed`). Only catch blocks set `success: false` (real engine crashes).
Affected tools:
- `altimate_core_validate` — validation errors now emit `sql_quality`
- `altimate_core_semantics` — semantic issues now emit `sql_quality`
- `altimate_core_policy` — policy violations now emit `sql_quality`
- `altimate_core_equivalence` — differences now emit `sql_quality`
- `altimate_core_fix` — unfixable errors now emit `sql_quality`
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: [AI-5975] remove hardcoded `dialect: "snowflake"` from core tools
- Remove `dialect` from metadata in 8 altimate-core/impact tools that don't
accept a dialect parameter (it was always hardcoded to "snowflake")
- Make `dialect` optional in `sql_quality` telemetry event type
- Only emit `dialect` when the tool actually provides it (sql-analyze,
sql-optimize, schema-diff still do via `args.dialect`)
- Tracked as #455 for adding proper dialect parameter support later
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* fix: [AI-5975] guard finding arrays with `Array.isArray` for defensive safety
If a dispatcher returns a non-array for `errors`, `violations`, `issues`,
or `changes`, the `?? []` fallback handles null/undefined but not other
types. `Array.isArray` prevents `.map()` from throwing on unexpected payloads.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>1 parent 7a85ad8 commit fe1d8a1
File tree
16 files changed
+572
-24
lines changed- packages/opencode
- src
- altimate
- native
- sql
- telemetry
- tools
- tool
- test/altimate
16 files changed
+572
-24
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
45 | 45 | | |
46 | 46 | | |
47 | 47 | | |
| 48 | + | |
48 | 49 | | |
49 | 50 | | |
50 | 51 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
405 | 405 | | |
406 | 406 | | |
407 | 407 | | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
408 | 423 | | |
409 | 424 | | |
410 | 425 | | |
| |||
774 | 789 | | |
775 | 790 | | |
776 | 791 | | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
777 | 808 | | |
778 | 809 | | |
779 | 810 | | |
| |||
Lines changed: 24 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| |||
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
22 | 39 | | |
23 | 40 | | |
24 | | - | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
25 | 47 | | |
26 | 48 | | |
27 | 49 | | |
28 | 50 | | |
29 | | - | |
| 51 | + | |
30 | 52 | | |
31 | 53 | | |
32 | 54 | | |
| |||
Lines changed: 16 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| |||
19 | 21 | | |
20 | 22 | | |
21 | 23 | | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
22 | 30 | | |
23 | 31 | | |
24 | | - | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
25 | 39 | | |
26 | 40 | | |
27 | 41 | | |
28 | 42 | | |
29 | | - | |
| 43 | + | |
30 | 44 | | |
31 | 45 | | |
32 | 46 | | |
| |||
Lines changed: 20 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
15 | | - | |
| 16 | + | |
| 17 | + | |
16 | 18 | | |
17 | | - | |
| 19 | + | |
18 | 20 | | |
19 | 21 | | |
20 | 22 | | |
| |||
28 | 30 | | |
29 | 31 | | |
30 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
31 | 41 | | |
32 | 42 | | |
33 | | - | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
34 | 50 | | |
35 | 51 | | |
36 | 52 | | |
37 | 53 | | |
38 | | - | |
| 54 | + | |
39 | 55 | | |
40 | 56 | | |
41 | 57 | | |
| |||
Lines changed: 19 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| |||
24 | 26 | | |
25 | 27 | | |
26 | 28 | | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
27 | 38 | | |
28 | 39 | | |
29 | | - | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
30 | 47 | | |
31 | 48 | | |
32 | 49 | | |
33 | 50 | | |
34 | | - | |
| 51 | + | |
35 | 52 | | |
36 | 53 | | |
37 | 54 | | |
| |||
Lines changed: 16 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| |||
21 | 23 | | |
22 | 24 | | |
23 | 25 | | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
24 | 32 | | |
25 | 33 | | |
26 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
27 | 41 | | |
28 | 42 | | |
29 | 43 | | |
30 | 44 | | |
31 | | - | |
| 45 | + | |
32 | 46 | | |
33 | 47 | | |
34 | 48 | | |
| |||
Lines changed: 19 additions & 4 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
| 4 | + | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| |||
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
14 | | - | |
| 15 | + | |
| 16 | + | |
15 | 17 | | |
16 | | - | |
| 18 | + | |
17 | 19 | | |
18 | 20 | | |
19 | 21 | | |
| |||
25 | 27 | | |
26 | 28 | | |
27 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
28 | 36 | | |
29 | 37 | | |
30 | | - | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
31 | 46 | | |
32 | 47 | | |
33 | 48 | | |
34 | 49 | | |
35 | | - | |
| 50 | + | |
36 | 51 | | |
37 | 52 | | |
38 | 53 | | |
| |||
0 commit comments