From eaaa1428c7f6b3492917d35f963ab55910704f82 Mon Sep 17 00:00:00 2001 From: zerone0x Date: Wed, 6 May 2026 20:08:22 +0000 Subject: [PATCH] fix: centralize severity ordering --- packages/core/src/__tests__/severity.test.ts | 12 ++++++++++++ packages/core/src/index.ts | 1 + packages/core/src/severity.ts | 14 ++++++++++++++ packages/deepsec/src/commands/export.ts | 11 +---------- packages/deepsec/src/pr-comment.ts | 16 +--------------- packages/deepsec/src/sandbox/partitioner.ts | 18 +++++++----------- packages/processor/src/enrich.ts | 10 +--------- packages/processor/src/index.ts | 10 +--------- 8 files changed, 38 insertions(+), 54 deletions(-) create mode 100644 packages/core/src/severity.ts diff --git a/packages/core/src/__tests__/severity.test.ts b/packages/core/src/__tests__/severity.test.ts index 4faa698..0d22ab1 100644 --- a/packages/core/src/__tests__/severity.test.ts +++ b/packages/core/src/__tests__/severity.test.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from "vitest"; import { findingSchema, revalidationSchema } from "../schemas.js"; +import { SEVERITY_ORDER } from "../severity.js"; describe("severity levels", () => { const baseFinding = { @@ -38,6 +39,17 @@ describe("severity levels", () => { it("rejects empty severity", () => { expect(() => findingSchema.parse({ ...baseFinding, severity: "" })).toThrow(); }); + + it("uses one canonical ordering including LOW", () => { + expect(SEVERITY_ORDER).toEqual({ + CRITICAL: 0, + HIGH: 1, + MEDIUM: 2, + HIGH_BUG: 3, + BUG: 4, + LOW: 5, + }); + }); }); describe("revalidation adjustedSeverity", () => { diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d92cdfd..53fdb37 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -3,4 +3,5 @@ export * from "./paths.js"; export * from "./plugin.js"; export * from "./run.js"; export * from "./schemas.js"; +export * from "./severity.js"; export * from "./types.js"; diff --git a/packages/core/src/severity.ts b/packages/core/src/severity.ts new file mode 100644 index 0000000..8a7d0ca --- /dev/null +++ b/packages/core/src/severity.ts @@ -0,0 +1,14 @@ +import type { Severity } from "./types.js"; + +/** + * Canonical severity ranking used for filtering and presentation. + * Lower numbers are more severe. + */ +export const SEVERITY_ORDER: Record = { + CRITICAL: 0, + HIGH: 1, + MEDIUM: 2, + HIGH_BUG: 3, + BUG: 4, + LOW: 5, +}; diff --git a/packages/deepsec/src/commands/export.ts b/packages/deepsec/src/commands/export.ts index 5ee73d4..4e64ba3 100644 --- a/packages/deepsec/src/commands/export.ts +++ b/packages/deepsec/src/commands/export.ts @@ -2,19 +2,10 @@ import crypto from "node:crypto"; import fs from "node:fs"; import path from "node:path"; import type { FileRecord, Finding, Severity } from "@deepsec/core"; -import { dataDir, getDataRoot, loadAllFileRecords } from "@deepsec/core"; +import { dataDir, getDataRoot, loadAllFileRecords, SEVERITY_ORDER } from "@deepsec/core"; import { BOLD, DIM, GREEN, RESET, YELLOW } from "../formatters.js"; import { resolveAgentType } from "../resolve-agent-type.js"; -const SEVERITY_ORDER: Record = { - CRITICAL: 0, - HIGH: 1, - HIGH_BUG: 2, - MEDIUM: 3, - BUG: 4, - LOW: 5, -}; - interface OwnerSummary { assignee?: string; assigneeSource?: "oncall" | "manager" | "top-contributor" | "last-committer"; diff --git a/packages/deepsec/src/pr-comment.ts b/packages/deepsec/src/pr-comment.ts index 11122c6..b52f4a7 100644 --- a/packages/deepsec/src/pr-comment.ts +++ b/packages/deepsec/src/pr-comment.ts @@ -1,18 +1,4 @@ -import { type FileRecord, loadAllFileRecords, type Severity } from "@deepsec/core"; - -/** - * Severity ordering used to sort findings within the PR comment. Mirrors - * the order in `packages/processor/src/index.ts:SEVERITY_ORDER` — keep them - * in sync if you add a tier. - */ -const SEVERITY_ORDER: Record = { - CRITICAL: 0, - HIGH: 1, - MEDIUM: 2, - HIGH_BUG: 3, - BUG: 4, - LOW: 5, -}; +import { type FileRecord, loadAllFileRecords, SEVERITY_ORDER, type Severity } from "@deepsec/core"; const SEVERITY_BADGE: Record = { CRITICAL: "🔴 CRITICAL", diff --git a/packages/deepsec/src/sandbox/partitioner.ts b/packages/deepsec/src/sandbox/partitioner.ts index ed80398..8e0a027 100644 --- a/packages/deepsec/src/sandbox/partitioner.ts +++ b/packages/deepsec/src/sandbox/partitioner.ts @@ -1,17 +1,13 @@ import fs from "node:fs"; import path from "node:path"; import type { FileRecord } from "@deepsec/core"; -import { dataDir, loadAllFileRecords } from "@deepsec/core"; +import { dataDir, loadAllFileRecords, SEVERITY_ORDER } from "@deepsec/core"; import { noiseScore } from "@deepsec/scanner"; import type { PartitionResult, SandboxSubcommand } from "./types.js"; -const SEVERITY_ORDER: Record = { - CRITICAL: 0, - HIGH: 1, - MEDIUM: 2, - HIGH_BUG: 3, - BUG: 4, -}; +function severityRank(severity: string): number { + return SEVERITY_ORDER[severity as keyof typeof SEVERITY_ORDER] ?? 99; +} /** * Load eligible files for the given command and split into N disjoint partitions. @@ -68,7 +64,7 @@ export function partitionFiles( if (r.findings.length === 0) return false; const unrevalidated = r.findings.filter((f) => { if (!opts.force && f.revalidation) return false; - if (opts.minSeverity && SEVERITY_ORDER[f.severity] > SEVERITY_ORDER[opts.minSeverity]) + if (opts.minSeverity && severityRank(f.severity) > severityRank(opts.minSeverity)) return false; return true; }); @@ -95,8 +91,8 @@ export function partitionFiles( eligible.sort((a, b) => { if (command === "revalidate") { // Sort by severity (CRITICAL first) - const aBest = Math.min(...a.findings.map((f) => SEVERITY_ORDER[f.severity] ?? 99)); - const bBest = Math.min(...b.findings.map((f) => SEVERITY_ORDER[f.severity] ?? 99)); + const aBest = Math.min(...a.findings.map((f) => severityRank(f.severity))); + const bBest = Math.min(...b.findings.map((f) => severityRank(f.severity))); if (aBest !== bBest) return aBest - bBest; } diff --git a/packages/processor/src/enrich.ts b/packages/processor/src/enrich.ts index d73b3bb..5c4299b 100644 --- a/packages/processor/src/enrich.ts +++ b/packages/processor/src/enrich.ts @@ -6,6 +6,7 @@ import { getRegistry, loadAllFileRecords, readProjectConfig, + SEVERITY_ORDER, writeFileRecord, } from "@deepsec/core"; @@ -153,15 +154,6 @@ interface EnrichProgress { total?: number; } -const SEVERITY_ORDER: Record = { - CRITICAL: 0, - HIGH: 1, - HIGH_BUG: 2, - MEDIUM: 3, - BUG: 4, - LOW: 5, -}; - export async function enrich(params: { projectId: string; filter?: string; diff --git a/packages/processor/src/index.ts b/packages/processor/src/index.ts index 99c9cd1..e3ba803 100644 --- a/packages/processor/src/index.ts +++ b/packages/processor/src/index.ts @@ -15,6 +15,7 @@ import { readProjectConfig, readRunMeta, registerActiveRun, + SEVERITY_ORDER, writeFileRecord, writeRunMeta, } from "@deepsec/core"; @@ -806,15 +807,6 @@ export async function process(params: { // --- Revalidation --- -const SEVERITY_ORDER: Record = { - CRITICAL: 0, - HIGH: 1, - MEDIUM: 2, - HIGH_BUG: 3, - BUG: 4, - LOW: 5, -}; - export async function revalidate(params: { projectId: string; runId?: string;