Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions packages/opencode/src/altimate/telemetry/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1468,6 +1468,16 @@ export namespace Telemetry {
class: Telemetry.Event & { type: "core_failure" } extends { error_class: infer C } ? C : never
keywords: string[]
}> = [
// altimate_change start — permission denial/rejection first: these messages embed the user's
// rule patterns or feedback (e.g. "dbt parse *"), which would otherwise match parse_error etc.
{
class: "permission",
keywords: [
"the user has specified a rule which prevents you from using this specific tool call",
"the user rejected permission to use this specific tool call",
],
},
// altimate_change end
{ class: "parse_error", keywords: ["parse", "syntax", "binder", "unexpected token", "sqlglot"] },
{
class: "connection",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { describe, expect, test } from "bun:test"
import { Telemetry } from "../../src/altimate/telemetry"
import { PermissionNext } from "../../src/permission/next"
import { PermissionV1 } from "@opencode-ai/core/v1/permission"

describe("classifyError: permission denials embedding user rules", () => {
const ruleset = [
{ permission: "bash", pattern: "*", action: "ask" },
{ permission: "bash", pattern: "dbt parse *", action: "allow" },
{ permission: "bash", pattern: "rm -rf *", action: "deny" },
] as any

test("config-rule denial is permission even when a rule pattern mentions parse", () => {
const msg = new PermissionNext.DeniedError(ruleset).message
expect(Telemetry.classifyError(msg)).toBe("permission")
expect(Telemetry.classifyError(`Error: ${msg}`)).toBe("permission")
})

test("core v1 denial is permission", () => {
const msg = new PermissionV1.DeniedError({ ruleset }).message
expect(Telemetry.classifyError(msg)).toBe("permission")
})

test("user rejection with feedback is permission even when feedback mentions syntax", () => {
const msg = new PermissionNext.CorrectedError("fix the syntax first").message
expect(Telemetry.classifyError(msg)).toBe("permission")
expect(Telemetry.classifyError(new PermissionNext.RejectedError().message)).toBe("permission")
})

test("genuine parse errors still classify as parse_error", () => {
expect(Telemetry.classifyError("Parse error at line 3: unexpected token")).toBe("parse_error")
})
})
Loading