@kevinrabun/judges 3.51.0 → 3.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/chat-notify.d.ts +9 -0
- package/dist/commands/chat-notify.d.ts.map +1 -0
- package/dist/commands/chat-notify.js +259 -0
- package/dist/commands/chat-notify.js.map +1 -0
- package/dist/commands/code-similarity.d.ts +9 -0
- package/dist/commands/code-similarity.d.ts.map +1 -0
- package/dist/commands/code-similarity.js +232 -0
- package/dist/commands/code-similarity.js.map +1 -0
- package/dist/commands/compliance-weight.d.ts +9 -0
- package/dist/commands/compliance-weight.d.ts.map +1 -0
- package/dist/commands/compliance-weight.js +273 -0
- package/dist/commands/compliance-weight.js.map +1 -0
- package/dist/commands/cross-pr-regression.d.ts +9 -0
- package/dist/commands/cross-pr-regression.d.ts.map +1 -0
- package/dist/commands/cross-pr-regression.js +298 -0
- package/dist/commands/cross-pr-regression.js.map +1 -0
- package/dist/commands/design-audit.d.ts +9 -0
- package/dist/commands/design-audit.d.ts.map +1 -0
- package/dist/commands/design-audit.js +302 -0
- package/dist/commands/design-audit.js.map +1 -0
- package/dist/commands/doc-drift.d.ts +9 -0
- package/dist/commands/doc-drift.d.ts.map +1 -0
- package/dist/commands/doc-drift.js +259 -0
- package/dist/commands/doc-drift.js.map +1 -0
- package/dist/commands/exception-consistency.d.ts +7 -0
- package/dist/commands/exception-consistency.d.ts.map +1 -0
- package/dist/commands/exception-consistency.js +193 -0
- package/dist/commands/exception-consistency.js.map +1 -0
- package/dist/commands/impact-scan.d.ts +9 -0
- package/dist/commands/impact-scan.d.ts.map +1 -0
- package/dist/commands/impact-scan.js +282 -0
- package/dist/commands/impact-scan.js.map +1 -0
- package/dist/commands/judge-learn.d.ts +9 -0
- package/dist/commands/judge-learn.d.ts.map +1 -0
- package/dist/commands/judge-learn.js +218 -0
- package/dist/commands/judge-learn.js.map +1 -0
- package/dist/commands/model-report.d.ts +9 -0
- package/dist/commands/model-report.d.ts.map +1 -0
- package/dist/commands/model-report.js +195 -0
- package/dist/commands/model-report.js.map +1 -0
- package/dist/commands/refactor-safety.d.ts +9 -0
- package/dist/commands/refactor-safety.d.ts.map +1 -0
- package/dist/commands/refactor-safety.js +274 -0
- package/dist/commands/refactor-safety.js.map +1 -0
- package/dist/commands/remediation-lib.d.ts +9 -0
- package/dist/commands/remediation-lib.d.ts.map +1 -0
- package/dist/commands/remediation-lib.js +266 -0
- package/dist/commands/remediation-lib.js.map +1 -0
- package/dist/commands/resource-cleanup.d.ts +7 -0
- package/dist/commands/resource-cleanup.d.ts.map +1 -0
- package/dist/commands/resource-cleanup.js +236 -0
- package/dist/commands/resource-cleanup.js.map +1 -0
- package/dist/commands/team-trust.d.ts +8 -0
- package/dist/commands/team-trust.d.ts.map +1 -0
- package/dist/commands/team-trust.js +175 -0
- package/dist/commands/team-trust.js.map +1 -0
- package/dist/commands/trust-adaptive.d.ts +9 -0
- package/dist/commands/trust-adaptive.d.ts.map +1 -0
- package/dist/commands/trust-adaptive.js +194 -0
- package/dist/commands/trust-adaptive.js.map +1 -0
- package/dist/commands/watch-judge.d.ts +8 -0
- package/dist/commands/watch-judge.d.ts.map +1 -0
- package/dist/commands/watch-judge.js +180 -0
- package/dist/commands/watch-judge.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource cleanup — validate that allocated resources are properly
|
|
3
|
+
* freed: file handles, DB connections, timers, event listeners,
|
|
4
|
+
* streams with try-finally or equivalent cleanup mechanisms.
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, readdirSync, statSync } from "fs";
|
|
7
|
+
import { join, extname } from "path";
|
|
8
|
+
// ─── File Collection ────────────────────────────────────────────────────────
|
|
9
|
+
const CODE_EXTS = new Set([".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".py", ".java", ".cs", ".go"]);
|
|
10
|
+
function collectFiles(dir, max = 500) {
|
|
11
|
+
const files = [];
|
|
12
|
+
function walk(d) {
|
|
13
|
+
if (files.length >= max)
|
|
14
|
+
return;
|
|
15
|
+
let entries;
|
|
16
|
+
try {
|
|
17
|
+
entries = readdirSync(d);
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
for (const e of entries) {
|
|
23
|
+
if (files.length >= max)
|
|
24
|
+
return;
|
|
25
|
+
if (e.startsWith(".") || e === "node_modules" || e === "dist" || e === "build")
|
|
26
|
+
continue;
|
|
27
|
+
const full = join(d, e);
|
|
28
|
+
try {
|
|
29
|
+
if (statSync(full).isDirectory())
|
|
30
|
+
walk(full);
|
|
31
|
+
else if (CODE_EXTS.has(extname(full)))
|
|
32
|
+
files.push(full);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
/* skip */
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
walk(dir);
|
|
40
|
+
return files;
|
|
41
|
+
}
|
|
42
|
+
const RESOURCE_PATTERNS = [
|
|
43
|
+
{
|
|
44
|
+
name: "file-handle",
|
|
45
|
+
openRegex: /\b(openSync|createReadStream|createWriteStream|fs\.open)\s*\(/,
|
|
46
|
+
closeRegex: /\b(closeSync|\.close\(|\.destroy\(|\.end\()/,
|
|
47
|
+
guardRegex: /\b(finally|using|dispose|\.close\(|\.destroy\()/,
|
|
48
|
+
severity: "high",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "db-connection",
|
|
52
|
+
openRegex: /\b(createConnection|createPool|\.connect\(|new\s+Client\(|getConnection\()/,
|
|
53
|
+
closeRegex: /\b(\.end\(|\.close\(|\.release\(|\.disconnect\(|\.destroy\()/,
|
|
54
|
+
guardRegex: /\b(finally|\.release\(|\.end\(|pool\.end|disconnect)/,
|
|
55
|
+
severity: "high",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: "timer",
|
|
59
|
+
openRegex: /\b(setInterval|setTimeout)\s*\(/,
|
|
60
|
+
closeRegex: /\b(clearInterval|clearTimeout)\s*\(/,
|
|
61
|
+
guardRegex: /\b(clearInterval|clearTimeout|finally)/,
|
|
62
|
+
severity: "medium",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "event-listener",
|
|
66
|
+
openRegex: /\b(addEventListener|\.on\(|\.addListener\()/,
|
|
67
|
+
closeRegex: /\b(removeEventListener|\.off\(|\.removeListener\(|\.removeAllListeners\()/,
|
|
68
|
+
guardRegex: /\b(removeEventListener|\.off\(|\.removeListener\(|dispose|finally)/,
|
|
69
|
+
severity: "medium",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: "stream",
|
|
73
|
+
openRegex: /\b(createReadStream|createWriteStream|new\s+Readable|new\s+Writable|pipeline\()/,
|
|
74
|
+
closeRegex: /\b(\.end\(|\.destroy\(|\.close\(|pipeline\()/,
|
|
75
|
+
guardRegex: /\b(finally|\.destroy\(|\.end\(|pipeline|using)/,
|
|
76
|
+
severity: "high",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: "child-process",
|
|
80
|
+
openRegex: /\b(spawn|exec|execFile|fork)\s*\(/,
|
|
81
|
+
closeRegex: /\b(\.kill\(|\.disconnect\()/,
|
|
82
|
+
guardRegex: /\b(\.kill\(|finally|\.on\(\s*['"]exit)/,
|
|
83
|
+
severity: "medium",
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
87
|
+
function analyzeFile(filePath) {
|
|
88
|
+
let content;
|
|
89
|
+
try {
|
|
90
|
+
content = readFileSync(filePath, "utf-8");
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return [];
|
|
94
|
+
}
|
|
95
|
+
const lines = content.split("\n");
|
|
96
|
+
const issues = [];
|
|
97
|
+
for (const pattern of RESOURCE_PATTERNS) {
|
|
98
|
+
// Find all opens
|
|
99
|
+
for (let i = 0; i < lines.length; i++) {
|
|
100
|
+
if (pattern.openRegex.test(lines[i])) {
|
|
101
|
+
// Check if a corresponding close or guard exists in the surrounding function
|
|
102
|
+
const functionBlock = extractFunctionBlock(lines, i);
|
|
103
|
+
const hasClose = pattern.closeRegex.test(functionBlock);
|
|
104
|
+
const hasGuard = pattern.guardRegex.test(functionBlock);
|
|
105
|
+
if (!hasClose) {
|
|
106
|
+
issues.push({
|
|
107
|
+
file: filePath,
|
|
108
|
+
line: i + 1,
|
|
109
|
+
kind: `${pattern.name}-no-close`,
|
|
110
|
+
resource: pattern.name,
|
|
111
|
+
message: `${pattern.name} opened but no corresponding close/cleanup found in surrounding scope`,
|
|
112
|
+
severity: pattern.severity,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else if (!hasGuard) {
|
|
116
|
+
issues.push({
|
|
117
|
+
file: filePath,
|
|
118
|
+
line: i + 1,
|
|
119
|
+
kind: `${pattern.name}-no-guard`,
|
|
120
|
+
resource: pattern.name,
|
|
121
|
+
message: `${pattern.name} is closed but not in a finally/dispose block — may leak on exception`,
|
|
122
|
+
severity: "low",
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
// Detect try blocks without finally when resources are opened inside
|
|
129
|
+
const tryRegex = /\btry\s*\{/g;
|
|
130
|
+
let match;
|
|
131
|
+
while ((match = tryRegex.exec(content)) !== null) {
|
|
132
|
+
const pos = match.index;
|
|
133
|
+
const lineNum = content.substring(0, pos).split("\n").length;
|
|
134
|
+
const remaining = content.substring(pos);
|
|
135
|
+
// Check if this try block has a finally
|
|
136
|
+
const hasFinally = /\bfinally\s*\{/.test(remaining.substring(0, 500));
|
|
137
|
+
if (!hasFinally) {
|
|
138
|
+
// Check if resource operations exist inside the try
|
|
139
|
+
const tryBlock = remaining.substring(0, 500);
|
|
140
|
+
const hasResourceOp = RESOURCE_PATTERNS.some((p) => p.openRegex.test(tryBlock));
|
|
141
|
+
if (hasResourceOp) {
|
|
142
|
+
issues.push({
|
|
143
|
+
file: filePath,
|
|
144
|
+
line: lineNum,
|
|
145
|
+
kind: "try-without-finally",
|
|
146
|
+
resource: "mixed",
|
|
147
|
+
message: "try block contains resource operations but no finally block for cleanup",
|
|
148
|
+
severity: "medium",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return issues;
|
|
154
|
+
}
|
|
155
|
+
function extractFunctionBlock(lines, startLine) {
|
|
156
|
+
// Walk backwards to find function/method boundary, then forward to end
|
|
157
|
+
let start = Math.max(0, startLine - 30);
|
|
158
|
+
const end = Math.min(lines.length, startLine + 50);
|
|
159
|
+
for (let i = startLine; i >= Math.max(0, startLine - 30); i--) {
|
|
160
|
+
if (/\b(function|async\s+function|=>\s*\{|class\s|constructor|ngOnInit|componentDidMount)/.test(lines[i])) {
|
|
161
|
+
start = i;
|
|
162
|
+
break;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return lines.slice(start, end).join("\n");
|
|
166
|
+
}
|
|
167
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
168
|
+
export function runResourceCleanup(argv) {
|
|
169
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
170
|
+
console.log(`
|
|
171
|
+
judges resource-cleanup — Validate resource cleanup patterns
|
|
172
|
+
|
|
173
|
+
Usage:
|
|
174
|
+
judges resource-cleanup [dir]
|
|
175
|
+
judges resource-cleanup src/ --severity high
|
|
176
|
+
judges resource-cleanup --format json
|
|
177
|
+
|
|
178
|
+
Options:
|
|
179
|
+
[dir] Directory to scan (default: .)
|
|
180
|
+
--severity <level> Filter by minimum severity (high|medium|low)
|
|
181
|
+
--format json JSON output
|
|
182
|
+
--help, -h Show this help
|
|
183
|
+
|
|
184
|
+
Resources checked:
|
|
185
|
+
• File handles (open/close)
|
|
186
|
+
• Database connections (connect/end)
|
|
187
|
+
• Timers (setInterval/clearInterval)
|
|
188
|
+
• Event listeners (on/off)
|
|
189
|
+
• Streams (createReadStream/destroy)
|
|
190
|
+
• Child processes (spawn/kill)
|
|
191
|
+
`);
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
195
|
+
const severityFilter = argv.find((_a, i) => argv[i - 1] === "--severity") || "low";
|
|
196
|
+
const dir = argv.find((a) => !a.startsWith("-") && argv.indexOf(a) > 0) || ".";
|
|
197
|
+
const severityOrder = { high: 3, medium: 2, low: 1 };
|
|
198
|
+
const minSev = severityOrder[severityFilter] || 1;
|
|
199
|
+
const files = collectFiles(dir);
|
|
200
|
+
const allIssues = [];
|
|
201
|
+
for (const f of files) {
|
|
202
|
+
const issues = analyzeFile(f);
|
|
203
|
+
allIssues.push(...issues.filter((x) => severityOrder[x.severity] >= minSev));
|
|
204
|
+
}
|
|
205
|
+
allIssues.sort((a, b) => severityOrder[b.severity] - severityOrder[a.severity]);
|
|
206
|
+
if (format === "json") {
|
|
207
|
+
console.log(JSON.stringify({ issues: allIssues, filesScanned: files.length, timestamp: new Date().toISOString() }, null, 2));
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
console.log(`\n Resource Cleanup — ${files.length} files scanned, ${allIssues.length} issue(s)\n ──────────────────────────`);
|
|
211
|
+
if (allIssues.length === 0) {
|
|
212
|
+
console.log(" ✅ No resource cleanup issues detected");
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
const byResource = new Map();
|
|
216
|
+
for (const issue of allIssues) {
|
|
217
|
+
byResource.set(issue.resource, (byResource.get(issue.resource) || 0) + 1);
|
|
218
|
+
}
|
|
219
|
+
console.log("\n By resource type:");
|
|
220
|
+
for (const [res, count] of byResource) {
|
|
221
|
+
console.log(` ${res}: ${count} issue(s)`);
|
|
222
|
+
}
|
|
223
|
+
console.log("\n Details:");
|
|
224
|
+
for (const issue of allIssues.slice(0, 50)) {
|
|
225
|
+
const icon = issue.severity === "high" ? "🔴" : issue.severity === "medium" ? "🟡" : "⚪";
|
|
226
|
+
console.log(` ${icon} [${issue.severity}] ${issue.file}:${issue.line}`);
|
|
227
|
+
console.log(` ${issue.message}`);
|
|
228
|
+
}
|
|
229
|
+
if (allIssues.length > 50) {
|
|
230
|
+
console.log(`\n ... and ${allIssues.length - 50} more issue(s)`);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
console.log("");
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
//# sourceMappingURL=resource-cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resource-cleanup.js","sourceRoot":"","sources":["../../src/commands/resource-cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team trust — aggregate trust profiles across team members to
|
|
3
|
+
* build collective trust profiles with per-team sensitivity.
|
|
4
|
+
*
|
|
5
|
+
* All data stored locally in `.judges-team-trust/`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runTeamTrust(argv: string[]): void;
|
|
8
|
+
//# sourceMappingURL=team-trust.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-trust.d.ts","sourceRoot":"","sources":["../../src/commands/team-trust.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwGH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsHjD"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Team trust — aggregate trust profiles across team members to
|
|
3
|
+
* build collective trust profiles with per-team sensitivity.
|
|
4
|
+
*
|
|
5
|
+
* All data stored locally in `.judges-team-trust/`.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
10
|
+
const DATA_DIR = ".judges-team-trust";
|
|
11
|
+
function ensureDir() {
|
|
12
|
+
if (!existsSync(DATA_DIR))
|
|
13
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
14
|
+
}
|
|
15
|
+
function loadMembers() {
|
|
16
|
+
const file = join(DATA_DIR, "members.json");
|
|
17
|
+
if (!existsSync(file))
|
|
18
|
+
return [];
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return [];
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function saveMembers(members) {
|
|
27
|
+
ensureDir();
|
|
28
|
+
writeFileSync(join(DATA_DIR, "members.json"), JSON.stringify(members, null, 2));
|
|
29
|
+
}
|
|
30
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
31
|
+
function computeTeamProfiles(members) {
|
|
32
|
+
const teams = new Map();
|
|
33
|
+
for (const m of members) {
|
|
34
|
+
const list = teams.get(m.team) || [];
|
|
35
|
+
list.push(m);
|
|
36
|
+
teams.set(m.team, list);
|
|
37
|
+
}
|
|
38
|
+
const profiles = [];
|
|
39
|
+
for (const [team, teamMembers] of teams) {
|
|
40
|
+
const totalEvals = teamMembers.reduce((s, m) => s + m.evaluations, 0);
|
|
41
|
+
const totalFP = teamMembers.reduce((s, m) => s + m.falsePositives, 0);
|
|
42
|
+
const totalTP = teamMembers.reduce((s, m) => s + m.truePositives, 0);
|
|
43
|
+
const avgScore = teamMembers.length > 0 ? Math.round(teamMembers.reduce((s, m) => s + m.avgScore, 0) / teamMembers.length) : 0;
|
|
44
|
+
const fpRate = totalEvals > 0 ? Math.round((totalFP / totalEvals) * 100) : 0;
|
|
45
|
+
const tpRate = totalEvals > 0 ? Math.round((totalTP / totalEvals) * 100) : 0;
|
|
46
|
+
let sensitivity;
|
|
47
|
+
let recommendation;
|
|
48
|
+
if (avgScore >= 80 && fpRate > 30) {
|
|
49
|
+
sensitivity = "relaxed";
|
|
50
|
+
recommendation = "High FP rate suggests judges are too strict for this team — relax non-critical judges";
|
|
51
|
+
}
|
|
52
|
+
else if (avgScore < 60) {
|
|
53
|
+
sensitivity = "strict";
|
|
54
|
+
recommendation = "Low scores suggest team needs stricter evaluation and mentoring";
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
sensitivity = "normal";
|
|
58
|
+
recommendation = "Team performing at expected level — maintain current settings";
|
|
59
|
+
}
|
|
60
|
+
profiles.push({
|
|
61
|
+
team,
|
|
62
|
+
members: teamMembers.length,
|
|
63
|
+
avgTrustScore: avgScore,
|
|
64
|
+
totalEvaluations: totalEvals,
|
|
65
|
+
fpRate,
|
|
66
|
+
tpRate,
|
|
67
|
+
sensitivity,
|
|
68
|
+
recommendation,
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
return profiles.sort((a, b) => b.avgTrustScore - a.avgTrustScore);
|
|
72
|
+
}
|
|
73
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
74
|
+
export function runTeamTrust(argv) {
|
|
75
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
76
|
+
console.log(`
|
|
77
|
+
judges team-trust — Team-wide trust profile aggregation
|
|
78
|
+
|
|
79
|
+
Usage:
|
|
80
|
+
judges team-trust --record --member "alice" --team "backend" --score 85 --tp
|
|
81
|
+
judges team-trust --record --member "copilot" --team "ai" --score 60 --fp
|
|
82
|
+
judges team-trust --show
|
|
83
|
+
judges team-trust --team "backend"
|
|
84
|
+
|
|
85
|
+
Options:
|
|
86
|
+
--record Record feedback for a team member
|
|
87
|
+
--member <name> Member name
|
|
88
|
+
--team <name> Team name
|
|
89
|
+
--score <n> Evaluation score (0-100)
|
|
90
|
+
--pass Record pass
|
|
91
|
+
--fail Record fail
|
|
92
|
+
--fp Record false positive
|
|
93
|
+
--tp Record true positive
|
|
94
|
+
--show Show all team profiles
|
|
95
|
+
--format json JSON output
|
|
96
|
+
--help, -h Show this help
|
|
97
|
+
`);
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
101
|
+
const isRecord = argv.includes("--record");
|
|
102
|
+
const _isShow = argv.includes("--show");
|
|
103
|
+
const memberName = argv.find((_a, i) => argv[i - 1] === "--member") || "";
|
|
104
|
+
const teamName = argv.find((_a, i) => argv[i - 1] === "--team") || "";
|
|
105
|
+
const scoreArg = parseInt(argv.find((_a, i) => argv[i - 1] === "--score") || "0");
|
|
106
|
+
const isPass = argv.includes("--pass");
|
|
107
|
+
const isFail = argv.includes("--fail");
|
|
108
|
+
const isFp = argv.includes("--fp");
|
|
109
|
+
const isTp = argv.includes("--tp");
|
|
110
|
+
if (isRecord) {
|
|
111
|
+
if (!memberName || !teamName) {
|
|
112
|
+
console.error(" --member and --team are required");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const members = loadMembers();
|
|
116
|
+
let rec = members.find((m) => m.name === memberName && m.team === teamName);
|
|
117
|
+
if (!rec) {
|
|
118
|
+
rec = {
|
|
119
|
+
name: memberName,
|
|
120
|
+
team: teamName,
|
|
121
|
+
evaluations: 0,
|
|
122
|
+
passCount: 0,
|
|
123
|
+
failCount: 0,
|
|
124
|
+
falsePositives: 0,
|
|
125
|
+
truePositives: 0,
|
|
126
|
+
avgScore: 0,
|
|
127
|
+
lastUpdated: "",
|
|
128
|
+
};
|
|
129
|
+
members.push(rec);
|
|
130
|
+
}
|
|
131
|
+
rec.evaluations++;
|
|
132
|
+
if (isPass)
|
|
133
|
+
rec.passCount++;
|
|
134
|
+
if (isFail)
|
|
135
|
+
rec.failCount++;
|
|
136
|
+
if (isFp)
|
|
137
|
+
rec.falsePositives++;
|
|
138
|
+
if (isTp)
|
|
139
|
+
rec.truePositives++;
|
|
140
|
+
rec.avgScore = Math.round((rec.avgScore * (rec.evaluations - 1) + scoreArg) / rec.evaluations);
|
|
141
|
+
rec.lastUpdated = new Date().toISOString();
|
|
142
|
+
saveMembers(members);
|
|
143
|
+
console.log(` ✅ Recorded for ${memberName}@${teamName}: eval #${rec.evaluations}`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const members = loadMembers();
|
|
147
|
+
if (members.length === 0) {
|
|
148
|
+
console.log(" No team data yet. Use --record to add feedback.");
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const profiles = computeTeamProfiles(members);
|
|
152
|
+
// Filter by team if specified
|
|
153
|
+
const filtered = teamName ? profiles.filter((p) => p.team === teamName) : profiles;
|
|
154
|
+
if (format === "json") {
|
|
155
|
+
console.log(JSON.stringify({ profiles: filtered, totalMembers: members.length, timestamp: new Date().toISOString() }, null, 2));
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
console.log(`\n Team Trust Profiles — ${profiles.length} team(s), ${members.length} member(s)\n ──────────────────────────`);
|
|
159
|
+
for (const p of filtered) {
|
|
160
|
+
const icon = p.avgTrustScore >= 80 ? "🟢" : p.avgTrustScore >= 60 ? "🟡" : "🔴";
|
|
161
|
+
console.log(`\n ${icon} ${p.team} (${p.members} members)`);
|
|
162
|
+
console.log(` Trust: ${p.avgTrustScore}/100 | Evals: ${p.totalEvaluations} | FP: ${p.fpRate}% | TP: ${p.tpRate}%`);
|
|
163
|
+
console.log(` Sensitivity: ${p.sensitivity}`);
|
|
164
|
+
console.log(` 💡 ${p.recommendation}`);
|
|
165
|
+
// Show individual members
|
|
166
|
+
const teamMembers = members.filter((m) => m.team === p.team).sort((a, b) => b.avgScore - a.avgScore);
|
|
167
|
+
for (const m of teamMembers) {
|
|
168
|
+
const mIcon = m.avgScore >= 80 ? "✓" : m.avgScore >= 60 ? "~" : "✗";
|
|
169
|
+
console.log(` ${mIcon} ${m.name.padEnd(20)} score: ${m.avgScore} | evals: ${m.evaluations} | FP: ${m.falsePositives}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
console.log("");
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=team-trust.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"team-trust.js","sourceRoot":"","sources":["../../src/commands/team-trust.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust-adaptive — adjust judge sensitivity based on historical
|
|
3
|
+
* accuracy of developers or AI models. High-trust actors skip
|
|
4
|
+
* non-critical judges; low-trust get stricter scrutiny.
|
|
5
|
+
*
|
|
6
|
+
* All data stored locally in `.judges-trust/`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runTrustAdaptive(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=trust-adaptive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trust-adaptive.d.ts","sourceRoot":"","sources":["../../src/commands/trust-adaptive.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsGH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAoIrD"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust-adaptive — adjust judge sensitivity based on historical
|
|
3
|
+
* accuracy of developers or AI models. High-trust actors skip
|
|
4
|
+
* non-critical judges; low-trust get stricter scrutiny.
|
|
5
|
+
*
|
|
6
|
+
* All data stored locally in `.judges-trust/`.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
11
|
+
const DATA_DIR = ".judges-trust";
|
|
12
|
+
function ensureDir() {
|
|
13
|
+
if (!existsSync(DATA_DIR))
|
|
14
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
function loadRecords() {
|
|
17
|
+
const file = join(DATA_DIR, "records.json");
|
|
18
|
+
if (!existsSync(file))
|
|
19
|
+
return [];
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveRecords(records) {
|
|
28
|
+
ensureDir();
|
|
29
|
+
writeFileSync(join(DATA_DIR, "records.json"), JSON.stringify(records, null, 2));
|
|
30
|
+
}
|
|
31
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
32
|
+
// Non-critical judges that can be skipped for high-trust actors
|
|
33
|
+
const NON_CRITICAL_JUDGES = [
|
|
34
|
+
"style-consistency",
|
|
35
|
+
"naming-convention",
|
|
36
|
+
"comment-coverage",
|
|
37
|
+
"line-length",
|
|
38
|
+
"function-length",
|
|
39
|
+
"import-order",
|
|
40
|
+
];
|
|
41
|
+
function computeProfile(record) {
|
|
42
|
+
const passRate = record.evaluations > 0 ? record.passCount / record.evaluations : 0;
|
|
43
|
+
const fpRate = record.evaluations > 0 ? record.falsePositives / record.evaluations : 0;
|
|
44
|
+
// Trust score: weighted combination
|
|
45
|
+
const trustScore = Math.round(passRate * 40 + record.avgScore * 0.4 + fpRate * 20);
|
|
46
|
+
let trustLevel;
|
|
47
|
+
let sensitivity;
|
|
48
|
+
let skipJudges = [];
|
|
49
|
+
let escalate = false;
|
|
50
|
+
let detail;
|
|
51
|
+
if (record.evaluations < 5) {
|
|
52
|
+
trustLevel = "unknown";
|
|
53
|
+
sensitivity = "normal";
|
|
54
|
+
detail = `Only ${record.evaluations} evaluations — need ≥5 for trust assignment`;
|
|
55
|
+
}
|
|
56
|
+
else if (trustScore >= 75) {
|
|
57
|
+
trustLevel = "high";
|
|
58
|
+
sensitivity = "relaxed";
|
|
59
|
+
skipJudges = NON_CRITICAL_JUDGES;
|
|
60
|
+
detail = `High trust (${trustScore}) — skip ${skipJudges.length} non-critical judges`;
|
|
61
|
+
}
|
|
62
|
+
else if (trustScore >= 45) {
|
|
63
|
+
trustLevel = "medium";
|
|
64
|
+
sensitivity = "normal";
|
|
65
|
+
detail = `Medium trust (${trustScore}) — standard evaluation`;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
trustLevel = "low";
|
|
69
|
+
sensitivity = "strict";
|
|
70
|
+
escalate = true;
|
|
71
|
+
detail = `Low trust (${trustScore}) — strict evaluation with human escalation`;
|
|
72
|
+
}
|
|
73
|
+
return { actor: record.actor, trustLevel, trustScore, sensitivity, skipJudges, escalate, detail };
|
|
74
|
+
}
|
|
75
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
76
|
+
export function runTrustAdaptive(argv) {
|
|
77
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
78
|
+
console.log(`
|
|
79
|
+
judges trust-adaptive — Adaptive trust scoring for actors
|
|
80
|
+
|
|
81
|
+
Usage:
|
|
82
|
+
judges trust-adaptive --record --actor "copilot" --score 85 --pass
|
|
83
|
+
judges trust-adaptive --record --actor "dev-alice" --score 40 --fail
|
|
84
|
+
judges trust-adaptive --record --actor "copilot" --fp (record false positive)
|
|
85
|
+
judges trust-adaptive --show
|
|
86
|
+
judges trust-adaptive --profile "copilot"
|
|
87
|
+
|
|
88
|
+
Options:
|
|
89
|
+
--record Record evaluation result
|
|
90
|
+
--actor <name> Actor name (developer, AI model, team)
|
|
91
|
+
--score <n> Evaluation score (0-100)
|
|
92
|
+
--pass Record a pass
|
|
93
|
+
--fail Record a fail
|
|
94
|
+
--fp Record a false positive
|
|
95
|
+
--show Show all trust profiles
|
|
96
|
+
--profile <name> Show specific actor profile
|
|
97
|
+
--format json JSON output
|
|
98
|
+
--help, -h Show this help
|
|
99
|
+
|
|
100
|
+
Trust Levels:
|
|
101
|
+
high → Skip non-critical judges, relaxed thresholds
|
|
102
|
+
medium → Standard evaluation
|
|
103
|
+
low → Strict evaluation, escalation to human reviewer
|
|
104
|
+
unknown → <5 evaluations, standard evaluation
|
|
105
|
+
`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
109
|
+
const record = argv.includes("--record");
|
|
110
|
+
const _show = argv.includes("--show");
|
|
111
|
+
const profileName = argv.find((_a, i) => argv[i - 1] === "--profile");
|
|
112
|
+
const actor = argv.find((_a, i) => argv[i - 1] === "--actor") || "";
|
|
113
|
+
const scoreArg = parseInt(argv.find((_a, i) => argv[i - 1] === "--score") || "0");
|
|
114
|
+
const isPass = argv.includes("--pass");
|
|
115
|
+
const isFail = argv.includes("--fail");
|
|
116
|
+
const isFp = argv.includes("--fp");
|
|
117
|
+
if (record) {
|
|
118
|
+
if (!actor) {
|
|
119
|
+
console.error(" --actor is required for --record");
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const records = loadRecords();
|
|
123
|
+
let rec = records.find((r) => r.actor === actor);
|
|
124
|
+
if (!rec) {
|
|
125
|
+
rec = { actor, evaluations: 0, passCount: 0, failCount: 0, falsePositives: 0, avgScore: 0, lastUpdated: "" };
|
|
126
|
+
records.push(rec);
|
|
127
|
+
}
|
|
128
|
+
rec.evaluations++;
|
|
129
|
+
if (isPass)
|
|
130
|
+
rec.passCount++;
|
|
131
|
+
if (isFail)
|
|
132
|
+
rec.failCount++;
|
|
133
|
+
if (isFp)
|
|
134
|
+
rec.falsePositives++;
|
|
135
|
+
rec.avgScore = Math.round((rec.avgScore * (rec.evaluations - 1) + scoreArg) / rec.evaluations);
|
|
136
|
+
rec.lastUpdated = new Date().toISOString();
|
|
137
|
+
saveRecords(records);
|
|
138
|
+
console.log(` ✅ Recorded for ${actor}: eval #${rec.evaluations} (score: ${scoreArg}${isPass ? ", pass" : ""}${isFail ? ", fail" : ""}${isFp ? ", FP" : ""})`);
|
|
139
|
+
return;
|
|
140
|
+
}
|
|
141
|
+
const records = loadRecords();
|
|
142
|
+
if (records.length === 0) {
|
|
143
|
+
console.log(" No trust records yet. Use --record to add evaluations.");
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
if (profileName) {
|
|
147
|
+
const rec = records.find((r) => r.actor === profileName);
|
|
148
|
+
if (!rec) {
|
|
149
|
+
console.error(` Actor "${profileName}" not found.`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const profile = computeProfile(rec);
|
|
153
|
+
if (format === "json") {
|
|
154
|
+
console.log(JSON.stringify(profile, null, 2));
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
const icon = profile.trustLevel === "high"
|
|
158
|
+
? "🟢"
|
|
159
|
+
: profile.trustLevel === "medium"
|
|
160
|
+
? "🟡"
|
|
161
|
+
: profile.trustLevel === "low"
|
|
162
|
+
? "🔴"
|
|
163
|
+
: "⚪";
|
|
164
|
+
console.log(`\n ${icon} ${profile.actor}`);
|
|
165
|
+
console.log(` Trust: ${profile.trustLevel} (${profile.trustScore}/100)`);
|
|
166
|
+
console.log(` Sensitivity: ${profile.sensitivity}`);
|
|
167
|
+
console.log(` ${profile.detail}`);
|
|
168
|
+
if (profile.skipJudges.length > 0)
|
|
169
|
+
console.log(` Skip: ${profile.skipJudges.join(", ")}`);
|
|
170
|
+
if (profile.escalate)
|
|
171
|
+
console.log(` ⚠ Human escalation required`);
|
|
172
|
+
console.log(` Stats: ${rec.evaluations} evals, ${rec.passCount} pass, ${rec.failCount} fail, ${rec.falsePositives} FP`);
|
|
173
|
+
console.log("");
|
|
174
|
+
}
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
// Show all
|
|
178
|
+
const profiles = records.map(computeProfile);
|
|
179
|
+
profiles.sort((a, b) => b.trustScore - a.trustScore);
|
|
180
|
+
if (format === "json") {
|
|
181
|
+
console.log(JSON.stringify({ profiles, timestamp: new Date().toISOString() }, null, 2));
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
console.log(`\n Trust Profiles — ${profiles.length} actors\n ──────────────────────────`);
|
|
185
|
+
console.log(` ${"Actor".padEnd(25)} ${"Level".padEnd(10)} ${"Score".padEnd(8)} ${"Sensitivity".padEnd(12)} ${"Evals".padEnd(8)} Detail`);
|
|
186
|
+
console.log(` ${"─".repeat(25)} ${"─".repeat(10)} ${"─".repeat(8)} ${"─".repeat(12)} ${"─".repeat(8)} ${"─".repeat(30)}`);
|
|
187
|
+
for (const p of profiles) {
|
|
188
|
+
const icon = p.trustLevel === "high" ? "🟢" : p.trustLevel === "medium" ? "🟡" : p.trustLevel === "low" ? "🔴" : "⚪";
|
|
189
|
+
console.log(` ${icon} ${p.actor.padEnd(23)} ${p.trustLevel.padEnd(10)} ${String(p.trustScore).padEnd(8)} ${p.sensitivity.padEnd(12)} ${String(records.find((r) => r.actor === p.actor)?.evaluations || 0).padEnd(8)} ${p.detail}`);
|
|
190
|
+
}
|
|
191
|
+
console.log("");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
//# sourceMappingURL=trust-adaptive.js.map
|