fix(quality): clear the cycle's 11 net-new ESLint errors + make validate-release-green suppressions-aware

- executor-kiro/save-call-log/call-logs-correlation tests: replace 15 'as any'
  casts with typed shapes (net-new no-explicit-any errors from #6213/#6216);
  prune the now-empty suppression entries so the frozen baseline stays exact
- github-skills + usage/call-logs routes: raw toLowerCase().includes() search
  replaced by matchesSearch() (no-restricted-syntax — Turkish-safe search,
  behavior covered by tests/unit/call-logs-correlation-substring.test.ts and
  tests/unit/github-collector.test.ts)
- validate-release-green.mjs: run ESLint with --suppressions-location (match
  the npm run lint contract — frozen debt is not a release red) and raise the
  lint timeout 15->30min (a full pass takes ~14min alone; the 15min ceiling
  expired under concurrent suite load and surfaced as 'could not parse eslint
  json')
This commit is contained in:
Diego Rodrigues de Sa e Souza 2026-07-05 14:49:18 -03:00
parent 509fd5425c
commit fecf888fd9
7 changed files with 173 additions and 53 deletions

View file

@ -1392,11 +1392,6 @@
"count": 1
}
},
"tests/unit/executor-kiro.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 1
}
},
"tests/unit/executor-nlpcloud.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 2
@ -2002,11 +1997,6 @@
"count": 9
}
},
"tests/unit/save-call-log-persistence.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 7
}
},
"tests/unit/schema-coercion.test.ts": {
"@typescript-eslint/no-explicit-any": {
"count": 12

View file

@ -53,7 +53,9 @@ const npmCmd = process.platform === "win32" ? "npm.cmd" : "npm";
/** Read the committed ratchet baseline value for a metric (null if unknown). */
export function baselineValue(metric, root = ROOT) {
try {
const raw = JSON.parse(readFileSync(join(root, "config/quality/quality-baseline.json"), "utf8"));
const raw = JSON.parse(
readFileSync(join(root, "config/quality/quality-baseline.json"), "utf8")
);
const metrics = raw.metrics || raw;
const v = metrics?.[metric]?.value;
return typeof v === "number" ? v : null;
@ -178,7 +180,13 @@ function main() {
const hardCmd = (id, label, cmd, cmdArgs, opts) => {
announce(label);
const { code, out } = run(cmd, cmdArgs, opts);
record({ id, label, kind: "hard", ok: code === 0, detail: code === 0 ? "pass" : firstFailureLine(out) });
record({
id,
label,
kind: "hard",
ok: code === 0,
detail: code === 0 ? "pass" : firstFailureLine(out),
});
};
// A ratchet command (check:complexity, check:dead-code, …) exits 1 ONLY on a
@ -189,7 +197,13 @@ function main() {
const driftCmd = (id, label, cmd, cmdArgs, okDetail = "within baseline", opts) => {
announce(label);
const { code, out } = run(cmd, cmdArgs, opts);
record({ id, label, kind: "drift", ok: code === 0, detail: code === 0 ? okDetail : firstFailureLine(out) });
record({
id,
label,
kind: "drift",
ok: code === 0,
detail: code === 0 ? okDetail : firstFailureLine(out),
});
};
process.stderr.write("🔎 Release-green validation (current working tree)\n\n");
@ -198,14 +212,41 @@ function main() {
// ESLint: ONE pass → errors (hard) + warnings (drift)
{
announce("ESLint (errors + warnings — ~3-6min)");
const { out } = run("npx", ["eslint", ".", "--format", "json"], { timeout: 15 * 60 * 1000 });
announce("ESLint (errors + warnings — ~5-15min)");
// Suppressions-aware, matching `npm run lint` (Pacote 4 no-new-warnings): the frozen
// pre-existing debt in config/quality/eslint-suppressions.json must not count as
// errors here — only NET-NEW violations are release reds. Timeout raised: a full
// repo pass takes ~14min alone and this pre-flight often runs alongside test suites.
const { out } = run(
"npx",
[
"eslint",
".",
"--format",
"json",
"--suppressions-location",
"config/quality/eslint-suppressions.json",
],
{ timeout: 30 * 60 * 1000 }
);
const parsed = parseEslintJson(out);
if (!parsed) {
record({ id: "lint", label: "ESLint", kind: "hard", ok: false, detail: "could not parse eslint json" });
record({
id: "lint",
label: "ESLint",
kind: "hard",
ok: false,
detail: "could not parse eslint json",
});
} else {
const { errors, warnings } = eslintCounts(parsed);
record({ id: "lint-errors", label: "ESLint errors", kind: "hard", ok: errors === 0, detail: `${errors} error(s)` });
record({
id: "lint-errors",
label: "ESLint errors",
kind: "hard",
ok: errors === 0,
detail: `${errors} error(s)`,
});
const base = baselineValue("eslintWarnings");
const over = isDrift(warnings, base);
record({
@ -283,9 +324,20 @@ function main() {
driftCmd("complexity", "Cyclomatic complexity (ratchet)", npmCmd, ["run", "check:complexity"]);
driftCmd("dead-code", "Dead-code (ratchet)", npmCmd, ["run", "check:dead-code"]);
driftCmd("type-coverage", "Type coverage (ratchet)", npmCmd, ["run", "check:type-coverage"]);
driftCmd("compression-budget", "Compression budget (ratchet)", npmCmd, ["run", "check:compression-budget"]);
driftCmd("openapi-coverage", "OpenAPI route coverage (ratchet)", npmCmd, ["run", "check:openapi-coverage"]);
driftCmd("workflow-lint", "Workflow lint (zizmor ratchet)", npmCmd, ["run", "check:workflows", "--", "--ratchet"]);
driftCmd("compression-budget", "Compression budget (ratchet)", npmCmd, [
"run",
"check:compression-budget",
]);
driftCmd("openapi-coverage", "OpenAPI route coverage (ratchet)", npmCmd, [
"run",
"check:openapi-coverage",
]);
driftCmd("workflow-lint", "Workflow lint (zizmor ratchet)", npmCmd, [
"run",
"check:workflows",
"--",
"--ratchet",
]);
driftCmd("codeql-ratchet", "CodeQL alerts (ratchet)", npmCmd, ["run", "check:codeql-ratchet"]);
// Docs sync + fabricated-docs (strict) is a real-defect gate (invented env vars /
@ -298,15 +350,35 @@ function main() {
// with 15 such reds). They run SILENTLY for many minutes; the announce line above + these
// hard ceilings keep a long-but-healthy run from being mistaken for a hang (the ceiling also
// converts a genuine DB-handle hang into a visible failure instead of an infinite block).
hardCmd("unit", "Unit tests (full suite, CI concurrency — runs ~20-35min silently)", npmCmd, ["run", "test:unit:ci"], { timeout: 45 * 60 * 1000 });
hardCmd("vitest", "Vitest (MCP / autoCombo / cache — ~3-8min)", npmCmd, ["run", "test:vitest"], { timeout: 15 * 60 * 1000 });
hardCmd(
"unit",
"Unit tests (full suite, CI concurrency — runs ~20-35min silently)",
npmCmd,
["run", "test:unit:ci"],
{ timeout: 45 * 60 * 1000 }
);
hardCmd(
"vitest",
"Vitest (MCP / autoCombo / cache — ~3-8min)",
npmCmd,
["run", "test:vitest"],
{ timeout: 15 * 60 * 1000 }
);
// Integration tests run ONLY on the release PR full CI (PR→main), so an assertion
// regression here (e.g. a contributor flipping a Codex fingerprint key order) is
// invisible until release — run them in the pre-flight as a HARD gate.
hardCmd("integration", "Integration tests (~3-10min)", npmCmd, ["run", "test:integration"], { timeout: 20 * 60 * 1000 });
hardCmd("integration", "Integration tests (~3-10min)", npmCmd, ["run", "test:integration"], {
timeout: 20 * 60 * 1000,
});
}
if (WITH_BUILD) {
hardCmd("pack-artifact", "Package artifact (npm pack policy)", npmCmd, ["run", "check:pack-artifact"], { timeout: 20 * 60 * 1000 });
hardCmd(
"pack-artifact",
"Package artifact (npm pack policy)",
npmCmd,
["run", "check:pack-artifact"],
{ timeout: 20 * 60 * 1000 }
);
}
const { releaseGreen, hardFailures, drift } = computeVerdict(results);

View file

@ -11,6 +11,7 @@
*/
import { NextRequest, NextResponse } from "next/server";
import { searchGitHubSkills } from "@/lib/skills/githubCollector";
import { matchesSearch } from "@/shared/utils/turkishText";
import { buildErrorBody, sanitizeErrorMessage } from "@omniroute/open-sse/utils/error";
export const dynamic = "force-dynamic";
@ -31,9 +32,8 @@ export async function GET(request: NextRequest) {
let filtered = repos;
if (minScore > 0) filtered = filtered.filter((r) => r.score >= minScore);
if (query) {
const q = query.toLowerCase();
filtered = filtered.filter(
(r) => r.fullName.toLowerCase().includes(q) || r.description.toLowerCase().includes(q)
(r) => matchesSearch(r.fullName, query) || matchesSearch(r.description, query)
);
}

View file

@ -3,6 +3,7 @@ import { requireManagementAuth } from "@/lib/api/requireManagementAuth";
import { getCallLogs } from "@/lib/usageDb";
import { getCompletedDetails, getPendingById } from "@/lib/usage/usageHistory";
import { getProviderConnections } from "@/lib/localDb";
import { matchesSearch } from "@/shared/utils/turkishText";
type CallLogListRowsInput = {
logs: any[];
@ -147,10 +148,8 @@ export async function GET(request: Request) {
// (active + completed) that don't match — getCallLogs already filters
// the DB rows but activeEntries/completedEntries bypass it.
if (filter.correlationId) {
const cid = filter.correlationId.toLowerCase();
return NextResponse.json(
rows.filter((r: any) => (r.correlationId || "").toLowerCase().includes(cid))
);
const cid = filter.correlationId;
return NextResponse.json(rows.filter((r: any) => matchesSearch(r.correlationId || "", cid)));
}
return NextResponse.json(rows);

View file

@ -22,15 +22,54 @@ function seedLogs() {
db.prepare(
`INSERT OR REPLACE INTO call_logs (id, timestamp, method, path, status, model, provider, account, duration, tokens_in, tokens_out, correlation_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run("log-1", now, "POST", "/v1/chat/completions", 200, "gpt-4", "openai", "acc1", 100, 10, 20, "abc123-def456-ghi789");
).run(
"log-1",
now,
"POST",
"/v1/chat/completions",
200,
"gpt-4",
"openai",
"acc1",
100,
10,
20,
"abc123-def456-ghi789"
);
db.prepare(
`INSERT OR REPLACE INTO call_logs (id, timestamp, method, path, status, model, provider, account, duration, tokens_in, tokens_out, correlation_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run("log-2", now, "POST", "/v1/chat/completions", 200, "claude-3", "anthropic", "acc2", 200, 15, 30, "xyz999-uvw888-tsr777");
).run(
"log-2",
now,
"POST",
"/v1/chat/completions",
200,
"claude-3",
"anthropic",
"acc2",
200,
15,
30,
"xyz999-uvw888-tsr777"
);
db.prepare(
`INSERT OR REPLACE INTO call_logs (id, timestamp, method, path, status, model, provider, account, duration, tokens_in, tokens_out, correlation_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run("log-3", now, "POST", "/v1/chat/completions", 500, "gpt-4", "openai", "acc1", 50, 0, 0, null);
).run(
"log-3",
now,
"POST",
"/v1/chat/completions",
500,
"gpt-4",
"openai",
"acc1",
50,
0,
0,
null
);
}
// ── Exact match ───────────────────────────────────────────────────────────
@ -72,11 +111,24 @@ test("correlationId substring match returns multiple when shared", async () => {
db.prepare(
`INSERT OR REPLACE INTO call_logs (id, timestamp, method, path, status, model, provider, account, duration, tokens_in, tokens_out, correlation_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`
).run("log-4", now, "POST", "/v1/chat/completions", 200, "gpt-4", "openai", "acc1", 100, 10, 20, "abc123-RETRY-suffix");
).run(
"log-4",
now,
"POST",
"/v1/chat/completions",
200,
"gpt-4",
"openai",
"acc1",
100,
10,
20,
"abc123-RETRY-suffix"
);
const results = await callLogs.getCallLogs({ correlationId: "abc123" });
assert.equal(results.length, 2);
const ids = results.map((r: any) => r.id).sort();
const ids = results.map((r: { id: string }) => r.id).sort();
assert.deepEqual(ids, ["log-1", "log-4"]);
});
@ -94,7 +146,7 @@ test("rows with null correlationId are excluded from substring search", async ()
seedLogs();
// Search for a unique substring that only matches log-1
const results = await callLogs.getCallLogs({ correlationId: "ghi789" });
const ids = results.map((r: any) => r.id);
const ids = results.map((r: { id: string }) => r.id);
assert.ok(!ids.includes("log-3"), "null correlation_id rows must be excluded");
assert.equal(results.length, 1);
});

View file

@ -162,10 +162,10 @@ test("KiroExecutor.transformRequest removes the top-level model field", () => {
const result = executor.transformRequest("kiro-model", body, true, {});
assert.equal("model" in result, false);
assert.equal(
(result as any).conversationState.currentMessage.userInputMessage.modelId,
"kiro-model"
);
const kiroResult = result as unknown as {
conversationState: { currentMessage: { userInputMessage: { modelId: string } } };
};
assert.equal(kiroResult.conversationState.currentMessage.userInputMessage.modelId, "kiro-model");
});
test("KiroExecutor.transformRequest forwards additionalModelRequestFields (thinking) to AWS", () => {
@ -182,7 +182,10 @@ test("KiroExecutor.transformRequest forwards additionalModelRequestFields (think
},
};
const result = executor.transformRequest("kiro-model", body, true, {}) as any;
const result = executor.transformRequest("kiro-model", body, true, {}) as unknown as Record<
string,
unknown
>;
// The thinking control must survive the strict allowlist — otherwise graded
// reasoning never reaches CodeWhisperer (the field the openai-to-kiro
// translator builds would be silently dropped).

View file

@ -23,7 +23,7 @@ test("saveCallLog persists to DB with correlationId", async () => {
const row = db
.prepare("SELECT id, correlation_id, status, model FROM call_logs WHERE id = ?")
.get(testId) as any;
.get(testId) as Record<string, unknown>;
assert.ok(row, "row should exist in call_logs");
assert.equal(row.id, testId);
assert.equal(row.correlation_id, "test-correlation-id-123");
@ -50,7 +50,7 @@ test("saveCallLog persists null correlationId when not provided", async () => {
const row = db
.prepare("SELECT id, correlation_id FROM call_logs WHERE id = ?")
.get(testId) as any;
.get(testId) as Record<string, unknown>;
assert.ok(row, "row should exist");
assert.equal(row.correlation_id, null, "correlation_id should be null when not provided");
@ -74,7 +74,7 @@ test("getCallLogs returns correlationId", async () => {
});
const logs = await getCallLogs({ limit: 100 });
const found = logs.find((l: any) => l.id === testId);
const found = logs.find((l: { id: string }) => l.id === testId);
assert.ok(found, "log entry should be found via getCallLogs");
assert.equal(found.correlationId, "cid-roundtrip-test");
@ -83,12 +83,12 @@ test("getCallLogs returns correlationId", async () => {
test("call_logs table has correlation_id column", () => {
const db = getDbInstance();
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as any[];
const colNames = columns.map((c: any) => c.name);
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as { name: string }[];
const colNames = columns.map((c) => c.name);
assert.ok(colNames.includes("correlation_id"), "call_logs should have correlation_id column");
const indexes = db.prepare("PRAGMA index_list(call_logs)").all() as any[];
const idxNames = indexes.map((i: any) => i.name);
const indexes = db.prepare("PRAGMA index_list(call_logs)").all() as { name: string }[];
const idxNames = indexes.map((i) => i.name);
assert.ok(
idxNames.includes("idx_cl_correlation_id"),
"call_logs should have idx_cl_correlation_id index"
@ -97,8 +97,8 @@ test("call_logs table has correlation_id column", () => {
test("call_logs table has model_pinned column", () => {
const db = getDbInstance();
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as any[];
const colNames = columns.map((c: any) => c.name);
const columns = db.prepare("PRAGMA table_info(call_logs)").all() as { name: string }[];
const colNames = columns.map((c) => c.name);
assert.ok(colNames.includes("model_pinned"), "call_logs should have model_pinned column");
});
@ -118,7 +118,9 @@ test("saveCallLog persists modelPinned=true as 1", async () => {
modelPinned: true,
});
const row = db.prepare("SELECT id, model_pinned FROM call_logs WHERE id = ?").get(testId) as any;
const row = db
.prepare("SELECT id, model_pinned FROM call_logs WHERE id = ?")
.get(testId) as Record<string, unknown>;
assert.ok(row, "row should exist");
assert.equal(row.model_pinned, 1, "model_pinned should be 1 when modelPinned=true");
@ -141,7 +143,9 @@ test("saveCallLog persists modelPinned=false as 0", async () => {
modelPinned: false,
});
const row = db.prepare("SELECT id, model_pinned FROM call_logs WHERE id = ?").get(testId) as any;
const row = db
.prepare("SELECT id, model_pinned FROM call_logs WHERE id = ?")
.get(testId) as Record<string, unknown>;
assert.ok(row, "row should exist");
assert.equal(row.model_pinned, 0, "model_pinned should be 0 when modelPinned=false");
@ -165,7 +169,7 @@ test("getCallLogs returns modelPinned boolean", async () => {
});
const logs = await getCallLogs({ limit: 100 });
const found = logs.find((l: any) => l.id === testId);
const found = logs.find((l: { id: string }) => l.id === testId);
assert.ok(found, "log entry should be found via getCallLogs");
assert.equal(found.modelPinned, true, "getCallLogs should return modelPinned as boolean true");