Skip to content

Commit 526aa03

Browse files
committed
fix(issues): tighten area-label heuristics against template noise
Prefer title-scoped matches for platform/gui/cli and stronger full-body tokens so Environment OS fields do not blanket-label every bug report.
1 parent 05ecb40 commit 526aa03

2 files changed

Lines changed: 58 additions & 12 deletions

File tree

.github/scripts/issue-quality.cjs

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -322,50 +322,90 @@ const AREA_FIELD_TO_LABELS = {
322322
other: [],
323323
};
324324

325+
/**
326+
* Heuristic rules. `scope: "title"` avoids false hits from template Environment /
327+
* OS fields in the body; `scope: "full"` is for distinctive technical tokens.
328+
*/
325329
const AREA_HEURISTICS = [
326330
{
327331
label: "account-pool",
328-
re: /\b(oauth|reauth|needsreauth|quota|account pool|codex.?auth|auto[- ]?switch|failover|refresh token|plan_type|chatgpt[- ]account|reset credit)\b/i,
332+
scope: "full",
333+
re: /\b(oauth|reauth|needsreauth|account pool|codex.?auth|auto[- ]?switch|account failover|refresh token|plan_type|chatgpt[- ]account|reset credit)\b/i,
334+
},
335+
{
336+
label: "account-pool",
337+
scope: "title",
338+
re: /\b(quota|failover|pool account|account switch)\b/i,
329339
},
330340
{
331341
label: "catalog",
332-
re: /\b(catalog|model list|model visibility|virtual model|routed (catalog|entries|slug)|model slug)\b/i,
342+
scope: "full",
343+
re: /\b(model catalog|opencodex-catalog|model list|model visibility|virtual model|routed (catalog|entries|slug)|model slug)\b/i,
344+
},
345+
{
346+
label: "catalog",
347+
scope: "title",
348+
re: /\bcatalog\b/i,
333349
},
334350
{
335351
label: "gui",
336-
re: /\b(dashboard|\bgui\b|tray|sidebar|settings tab)\b/i,
352+
scope: "title",
353+
re: /\b(dashboard|\bgui\b|tray|sidebar|settings (page|tab|ui))\b/i,
337354
},
338355
{
339356
label: "cli",
357+
scope: "title",
340358
re: /\b(ocx\b|config\.toml|config inject)\b/i,
341359
},
342360
{
343361
label: "proxy",
344-
re: /\b(reverse[- ]proxy|management api|admin[- ]token|\/api\/\*|bind(s)? the (old )?port|proxy running)\b/i,
362+
scope: "full",
363+
re: /\b(reverse[- ]proxy|management api|admin[- ]token|\/api\/\*|bind(s)? the (old )?port)\b/i,
364+
},
365+
{
366+
label: "proxy",
367+
scope: "title",
368+
re: /\b(reverse[- ]proxy|management api|admin[- ]token)\b/i,
345369
},
346370
{
347371
label: "platform",
348-
re: /\b(windows|macos|mac os|win32|darwin|wsl|winsw|launchd|systemd|icacls|\bacl\b)\b/i,
372+
scope: "full",
373+
re: /\b(winsw|launchd|schtasks|icacls|windows-latest|tray host|scheduler backend)\b/i,
374+
},
375+
{
376+
label: "platform",
377+
scope: "title",
378+
re: /\b(\[windows\]|\[macos\]|windows|macos|darwin|win32|wsl)\b/i,
349379
},
350380
{
351381
label: "streaming",
382+
scope: "full",
352383
re: /\b(sse|websocket|\bws\b|stream(ing)?\b.{0,40}\b(truncat|terminal)|terminal (sse )?frame|without a terminal)\b/i,
353384
},
354385
{
355386
label: "tools",
387+
scope: "full",
356388
re: /\b(tool_calls?|tool[- ]calls?|\bmcp\b|web[- ]search|tool[- ]recall)\b/i,
357389
},
358390
{
359391
label: "install",
392+
scope: "full",
360393
re: /\b(npm (global )?install|packaging|release asset|npx ocx)\b/i,
361394
},
362395
{
363396
label: "service",
397+
scope: "full",
364398
re: /\b(ocx service|winsw|scheduler backend|launchd service)\b/i,
365399
},
366400
{
367401
label: "provider",
368-
re: /\b(provider adapter|openai[- ]compatible|provider[- ]compat|adapter quirk|upstream api|built[- ]in provider|provider preset)\b/i,
402+
scope: "full",
403+
re: /\b(provider adapter|openai[- ]compatible|provider[- ]compat|adapter quirk|built[- ]in provider|provider preset)\b/i,
404+
},
405+
{
406+
label: "provider",
407+
scope: "title",
408+
re: /\b(\[provider\]|provider compat|openai[- ]compatible)\b/i,
369409
},
370410
];
371411

@@ -399,10 +439,15 @@ function mapAreaFieldToLabels(areaText) {
399439
* @returns {string[]}
400440
*/
401441
function heuristicAreaLabels(title, body) {
402-
const text = `${title || ""}\n${body || ""}`;
442+
const titleText = title || "";
443+
const fullText = `${titleText}\n${body || ""}`;
444+
const seen = new Set();
403445
const out = [];
404-
for (const { label, re } of AREA_HEURISTICS) {
405-
if (re.test(text)) out.push(label);
446+
for (const { label, re, scope } of AREA_HEURISTICS) {
447+
const text = scope === "title" ? titleText : fullText;
448+
if (!re.test(text) || seen.has(label)) continue;
449+
seen.add(label);
450+
out.push(label);
406451
}
407452
return out;
408453
}

.github/scripts/issue-quality.test.cjs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1737,12 +1737,13 @@ describe("detectAreaLabels", () => {
17371737
"### Area",
17381738
"Multiple areas",
17391739
"### Summary",
1740-
"OpenCodex dashboard shows no data when ACL/icacls hardening cannot be verified.",
1740+
"Management API fails closed when icacls hardening cannot be verified.",
17411741
].join("\n"),
17421742
labels: ["bug"],
17431743
});
1744-
assert.ok(labels.includes("gui"));
1745-
assert.ok(labels.includes("platform"));
1744+
assert.ok(labels.includes("gui"), `got ${labels.join(",")}`);
1745+
assert.ok(labels.includes("platform"), `got ${labels.join(",")}`);
1746+
assert.ok(labels.includes("proxy"), `got ${labels.join(",")}`);
17461747
assert.equal(labels.includes("kiro"), false);
17471748
assert.equal(labels.includes("gemini"), false);
17481749
assert.equal(labels.includes("windows"), false);

0 commit comments

Comments
 (0)