@viraatdas/rudder 2.10.21 → 2.10.23

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.
Files changed (47) hide show
  1. package/README.md +42 -0
  2. package/dist/improve/advisor.d.ts +10 -0
  3. package/dist/improve/advisor.js +115 -0
  4. package/dist/improve/advisor.js.map +1 -0
  5. package/dist/improve/collect.d.ts +10 -0
  6. package/dist/improve/collect.js +202 -0
  7. package/dist/improve/collect.js.map +1 -0
  8. package/dist/improve/gate.d.ts +17 -0
  9. package/dist/improve/gate.js +60 -0
  10. package/dist/improve/gate.js.map +1 -0
  11. package/dist/improve/index.d.ts +9 -0
  12. package/dist/improve/index.js +336 -0
  13. package/dist/improve/index.js.map +1 -0
  14. package/dist/improve/judge.d.ts +22 -0
  15. package/dist/improve/judge.js +101 -0
  16. package/dist/improve/judge.js.map +1 -0
  17. package/dist/improve/mine.d.ts +25 -0
  18. package/dist/improve/mine.js +173 -0
  19. package/dist/improve/mine.js.map +1 -0
  20. package/dist/improve/propose.d.ts +51 -0
  21. package/dist/improve/propose.js +150 -0
  22. package/dist/improve/propose.js.map +1 -0
  23. package/dist/improve/rank.d.ts +16 -0
  24. package/dist/improve/rank.js +49 -0
  25. package/dist/improve/rank.js.map +1 -0
  26. package/dist/improve/schedule.d.ts +1 -0
  27. package/dist/improve/schedule.js +93 -0
  28. package/dist/improve/schedule.js.map +1 -0
  29. package/dist/improve/ship.d.ts +25 -0
  30. package/dist/improve/ship.js +82 -0
  31. package/dist/improve/ship.js.map +1 -0
  32. package/dist/improve/state.d.ts +149 -0
  33. package/dist/improve/state.js +261 -0
  34. package/dist/improve/state.js.map +1 -0
  35. package/dist/main.js +11 -0
  36. package/dist/main.js.map +1 -1
  37. package/dist/native/darwin-arm64/rudder-native +0 -0
  38. package/dist/native/darwin-x64/rudder-native +0 -0
  39. package/dist/native/linux-x64/rudder-native +0 -0
  40. package/dist/state.js +2 -0
  41. package/dist/state.js.map +1 -1
  42. package/dist/task-summary.d.ts +6 -0
  43. package/dist/task-summary.js +6 -1
  44. package/dist/task-summary.js.map +1 -1
  45. package/dist/types.d.ts +16 -0
  46. package/dist/types.js.map +1 -1
  47. package/package.json +1 -1
@@ -0,0 +1,336 @@
1
+ import path from "node:path";
2
+ import { promises as fs } from "node:fs";
3
+ import { loadConfig, loadProjects } from "../state.js";
4
+ import { findRepoRoot } from "../git.js";
5
+ import { ensureDir, readJson, shortenHome } from "../util.js";
6
+ import { collectSessions, computeMetrics } from "./collect.js";
7
+ import { dedupeAgainstLedger, mineFindings } from "./mine.js";
8
+ import { rankFindings, targetMetricFor } from "./rank.js";
9
+ import { buildContextPack, prepareWorktree, removeWorktree, runImprovementAgent } from "./propose.js";
10
+ import { gateSummary, runGates } from "./gate.js";
11
+ import { judgePanel, panelSummary } from "./judge.js";
12
+ import { shipProposal } from "./ship.js";
13
+ import { scheduleCommand } from "./schedule.js";
14
+ import { AGENT_RUN_FLAT_USD, SpendMeter, acquireCycleLock, appendJsonl, ledgerPath, loadWatermark, logsDir, metricsPath, readJsonl, releaseCycleLock, reportsDir, resolveImproveSettings, saveWatermark, titleKey, } from "./state.js";
15
+ export async function runImprove(parsed) {
16
+ const sub = parsed.args[0] ?? "run";
17
+ switch (sub) {
18
+ case "run":
19
+ await runCycle({
20
+ dryRun: Boolean(parsed.flags.dryRun),
21
+ budgetUsd: parseBudgetArg(parsed.args),
22
+ });
23
+ return;
24
+ case "status":
25
+ await printStatus();
26
+ return;
27
+ case "report":
28
+ await printReport(parsed.args[1]);
29
+ return;
30
+ case "schedule":
31
+ await scheduleCommand(parsed.args[1] ?? "status");
32
+ return;
33
+ default:
34
+ throw new Error("Usage: rudder improve [run [--dry-run] [--budget-usd N] | status | report [date] | schedule install|uninstall|status]");
35
+ }
36
+ }
37
+ function parseBudgetArg(args) {
38
+ for (let i = 0; i < args.length; i += 1) {
39
+ const arg = args[i] ?? "";
40
+ if (arg === "--budget-usd") {
41
+ const value = Number.parseFloat(args[i + 1] ?? "");
42
+ if (Number.isFinite(value) && value > 0)
43
+ return value;
44
+ }
45
+ if (arg.startsWith("--budget-usd=")) {
46
+ const value = Number.parseFloat(arg.slice("--budget-usd=".length));
47
+ if (Number.isFinite(value) && value > 0)
48
+ return value;
49
+ }
50
+ }
51
+ return undefined;
52
+ }
53
+ async function runCycle(opts) {
54
+ const config = await loadConfig();
55
+ const settings = resolveImproveSettings(config, await resolveRudderRepo());
56
+ if (opts.budgetUsd)
57
+ settings.budgetUsd = opts.budgetUsd;
58
+ if (!settings.enabled) {
59
+ console.log("improve: disabled (RUDDER_IMPROVE=0 or improve.enabled=false); nothing to do.");
60
+ return;
61
+ }
62
+ if (!(await acquireCycleLock())) {
63
+ console.log("improve: another cycle holds the lock; skipping.");
64
+ return;
65
+ }
66
+ const cycleId = new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19);
67
+ const meter = new SpendMeter(settings.budgetUsd);
68
+ const lines = [];
69
+ const note = (line) => {
70
+ lines.push(line);
71
+ console.log(`improve: ${line}`);
72
+ };
73
+ try {
74
+ note(`cycle ${cycleId} starting (autonomy=${settings.autonomy}${opts.dryRun ? ", dry-run" : ""}, budget $${settings.budgetUsd})`);
75
+ // ---- Collect ----------------------------------------------------------
76
+ const watermark = await loadWatermark();
77
+ const { sessions, nextWatermark } = await collectSessions(settings, watermark);
78
+ const snapshot = computeMetrics(cycleId, sessions);
79
+ await appendJsonl(metricsPath(), snapshot);
80
+ note(`collected ${sessions.length} new session(s) across projects`);
81
+ const ledger = await readJsonl(ledgerPath());
82
+ // ---- Mine + rank -------------------------------------------------------
83
+ let selected = [];
84
+ let banked = [];
85
+ if (sessions.length > 0) {
86
+ const findings = dedupeAgainstLedger(await mineFindings({
87
+ cycleId,
88
+ sessions,
89
+ snapshot,
90
+ ledger,
91
+ model: settings.minerModel,
92
+ advisorModel: settings.advisorModel,
93
+ meter,
94
+ }), ledger);
95
+ const ranked = rankFindings(findings, settings.maxFindings);
96
+ selected = ranked.selected;
97
+ banked = ranked.banked;
98
+ note(`mined ${findings.length} finding(s): ${selected.length} selected, ${banked.length} banked`);
99
+ }
100
+ else {
101
+ note("no new sessions; skipping mining");
102
+ }
103
+ for (const finding of banked) {
104
+ await recordLedger(cycleId, finding, "banked", `score=${finding.score} frequency=${finding.frequency}`);
105
+ }
106
+ // ---- Observe / dry-run stop early --------------------------------------
107
+ if (opts.dryRun || settings.autonomy === "observe") {
108
+ for (const finding of selected) {
109
+ await recordLedger(cycleId, finding, "reported", `score=${finding.score} frequency=${finding.frequency}`);
110
+ note(`would propose: [${finding.class}] ${finding.title}`);
111
+ }
112
+ await finishCycle(cycleId, settings, snapshot, lines, meter);
113
+ await saveWatermark(nextWatermark);
114
+ return;
115
+ }
116
+ // ---- Propose → gate → judge → ship, sequentially ------------------------
117
+ for (const finding of selected) {
118
+ if (!meter.canAfford(AGENT_RUN_FLAT_USD + 0.5)) {
119
+ await recordLedger(cycleId, finding, "banked", `budget exhausted at $${meter.spentUsd().toFixed(2)}; frequency=${finding.frequency}`);
120
+ note(`budget exhausted; banked: ${finding.title}`);
121
+ continue;
122
+ }
123
+ note(`proposing: [${finding.class}] ${finding.title}`);
124
+ const history = ledger.filter((entry) => entry.titleKey === titleKey(finding.title));
125
+ let worktreeInfo;
126
+ try {
127
+ worktreeInfo = await prepareWorktree(settings, finding.id);
128
+ }
129
+ catch (error) {
130
+ await recordLedger(cycleId, finding, "agent-failed", `worktree setup failed: ${String(error).slice(0, 300)}`);
131
+ note(`worktree setup failed: ${String(error)}`);
132
+ continue;
133
+ }
134
+ const contextPack = buildContextPack({ finding, history, snapshot });
135
+ try {
136
+ meter.addFlat(AGENT_RUN_FLAT_USD);
137
+ let { proposal } = await runImprovementAgent({ settings, finding, ...worktreeInfo, contextPack });
138
+ if (!proposal) {
139
+ await recordLedger(cycleId, finding, "agent-failed", `agent produced no diff; frequency=${finding.frequency}`);
140
+ note("agent produced no diff (finding may be non-actionable); see agent log");
141
+ await removeWorktree(settings, worktreeInfo.worktree, worktreeInfo.branch);
142
+ continue;
143
+ }
144
+ let gate = await runGates(proposal);
145
+ if (!gate.passed) {
146
+ note(`gates failed (${gateSummary(gate)}); retrying once with failure context`);
147
+ meter.addFlat(AGENT_RUN_FLAT_USD);
148
+ const failure = gate.steps.find((step) => step.code !== 0);
149
+ const retry = await runImprovementAgent({
150
+ settings,
151
+ finding,
152
+ ...worktreeInfo,
153
+ contextPack,
154
+ extraNote: `Your previous attempt failed the deterministic gate "${failure?.name}". Failure output tail:\n${failure?.failureTail ?? ""}\nFix the failure while keeping the improvement; leave the worktree committed and clean.`,
155
+ });
156
+ proposal = retry.proposal ?? proposal;
157
+ gate = await runGates(proposal);
158
+ }
159
+ if (!gate.passed) {
160
+ await recordLedger(cycleId, finding, "gated-out", `${gateSummary(gate)}; frequency=${finding.frequency}`);
161
+ note(`gated out: ${gateSummary(gate)}`);
162
+ await removeWorktree(settings, worktreeInfo.worktree, worktreeInfo.branch);
163
+ continue;
164
+ }
165
+ note(`gates passed (${gateSummary(gate)})`);
166
+ const panel = await judgePanel({
167
+ proposal,
168
+ gate,
169
+ model: settings.judgeModel,
170
+ advisorModel: settings.advisorModel,
171
+ meter,
172
+ });
173
+ note(`judge panel: ${panelSummary(panel)}`);
174
+ if (!panel.ship) {
175
+ const reason = panel.votes.map((v) => `${v.lens}: ${v.notes}`).join(" | ").slice(0, 500);
176
+ await recordLedger(cycleId, finding, "judge-rejected", `${reason}; frequency=${finding.frequency}`);
177
+ await removeWorktree(settings, worktreeInfo.worktree, worktreeInfo.branch);
178
+ continue;
179
+ }
180
+ const shipped = await shipProposal({ settings, proposal });
181
+ if (shipped.status === "shipped") {
182
+ await recordLedger(cycleId, finding, "shipped", proposal.resultNote?.summary ?? proposal.diffStat, {
183
+ version: shipped.version,
184
+ targetMetric: targetMetricFor(finding.class),
185
+ metricAtShip: metricValue(snapshot, targetMetricFor(finding.class)),
186
+ });
187
+ note(`SHIPPED ${shipped.version}: ${finding.title}`);
188
+ }
189
+ else if (shipped.status === "branch-pushed") {
190
+ await recordLedger(cycleId, finding, "branch-pushed", proposal.resultNote?.summary ?? proposal.diffStat, {
191
+ branch: shipped.branch,
192
+ });
193
+ note(`pushed branch ${shipped.branch} for review`);
194
+ }
195
+ else {
196
+ await recordLedger(cycleId, finding, "push-conflict", `${shipped.detail}; frequency=${finding.frequency}`);
197
+ note(`push conflict: ${shipped.detail}`);
198
+ }
199
+ await removeWorktree(settings, worktreeInfo.worktree, worktreeInfo.branch);
200
+ }
201
+ catch (error) {
202
+ await recordLedger(cycleId, finding, "agent-failed", `${String(error).slice(0, 300)}; frequency=${finding.frequency}`);
203
+ note(`proposal errored: ${String(error)}`);
204
+ await removeWorktree(settings, worktreeInfo.worktree, worktreeInfo.branch);
205
+ }
206
+ }
207
+ await checkOutcomes(cycleId);
208
+ await finishCycle(cycleId, settings, snapshot, lines, meter);
209
+ await saveWatermark(nextWatermark);
210
+ }
211
+ finally {
212
+ await releaseCycleLock();
213
+ }
214
+ }
215
+ async function recordLedger(cycleId, finding, status, detail, extra = {}) {
216
+ await appendJsonl(ledgerPath(), {
217
+ ts: new Date().toISOString(),
218
+ cycleId,
219
+ findingId: finding.id,
220
+ titleKey: titleKey(finding.title),
221
+ title: finding.title,
222
+ class: finding.class,
223
+ status,
224
+ detail: detail.slice(0, 800),
225
+ ...extra,
226
+ });
227
+ }
228
+ // ---------------------------------------------------------------------------
229
+ // Outcome verification (§8 of the design): a shipped change only counts once
230
+ // the targeted metric moved. Compare mean metric across snapshots before vs
231
+ // after ship time, once at least a week and 3 post-ship snapshots have passed.
232
+ // ---------------------------------------------------------------------------
233
+ const OUTCOME_MIN_AGE_MS = 7 * 24 * 60 * 60 * 1000;
234
+ async function checkOutcomes(cycleId) {
235
+ const ledger = await readJsonl(ledgerPath());
236
+ const metrics = await readJsonl(metricsPath());
237
+ const judged = new Set(ledger.filter((e) => e.status === "outcome").map((e) => e.findingId));
238
+ for (const entry of ledger) {
239
+ if (entry.status !== "shipped" || judged.has(entry.findingId) || !entry.targetMetric)
240
+ continue;
241
+ if (Date.now() - Date.parse(entry.ts) < OUTCOME_MIN_AGE_MS)
242
+ continue;
243
+ const before = metrics.filter((m) => m.ts < entry.ts && m.runsSeen > 0).slice(-6);
244
+ const after = metrics.filter((m) => m.ts > entry.ts && m.runsSeen > 0);
245
+ if (before.length < 3 || after.length < 3)
246
+ continue;
247
+ const mean = (rows) => rows.reduce((sum, row) => sum + metricValue(row, entry.targetMetric), 0) / rows.length;
248
+ const beforeMean = mean(before);
249
+ const afterMean = mean(after);
250
+ const delta = beforeMean === 0 ? 0 : (afterMean - beforeMean) / beforeMean;
251
+ const outcome = delta <= -0.1 ? "confirmed" : delta >= 0.1 ? "regressed" : "no-effect";
252
+ await appendJsonl(ledgerPath(), {
253
+ ts: new Date().toISOString(),
254
+ cycleId,
255
+ findingId: entry.findingId,
256
+ titleKey: entry.titleKey,
257
+ title: entry.title,
258
+ class: entry.class,
259
+ status: "outcome",
260
+ detail: `${entry.targetMetric}: ${beforeMean.toFixed(4)} -> ${afterMean.toFixed(4)} (${(delta * 100).toFixed(1)}%) for ${entry.version ?? "?"}`,
261
+ outcome,
262
+ });
263
+ }
264
+ }
265
+ function metricValue(snapshot, key) {
266
+ const value = snapshot[key];
267
+ return typeof value === "number" ? value : 0;
268
+ }
269
+ // ---------------------------------------------------------------------------
270
+ // Reporting + status
271
+ // ---------------------------------------------------------------------------
272
+ async function finishCycle(cycleId, settings, snapshot, lines, meter) {
273
+ await ensureDir(reportsDir());
274
+ const reportPath = path.join(reportsDir(), `${cycleId}.md`);
275
+ const body = [
276
+ `# Improvement cycle ${cycleId}`,
277
+ "",
278
+ `- autonomy: ${settings.autonomy}`,
279
+ `- estimated spend: $${meter.spentUsd().toFixed(2)} of $${settings.budgetUsd}`,
280
+ `- metrics: ${JSON.stringify(snapshot)}`,
281
+ "",
282
+ "## Log",
283
+ ...lines.map((line) => `- ${line}`),
284
+ "",
285
+ `Agent + gate logs: ${shortenHome(logsDir())}`,
286
+ ].join("\n");
287
+ await fs.writeFile(reportPath, `${body}\n`, "utf8");
288
+ console.log(`improve: cycle report ${shortenHome(reportPath)} (est. spend $${meter.spentUsd().toFixed(2)})`);
289
+ }
290
+ async function printStatus() {
291
+ const metrics = await readJsonl(metricsPath());
292
+ const ledger = await readJsonl(ledgerPath());
293
+ const latest = metrics.at(-1);
294
+ console.log(`cycles recorded: ${metrics.length}`);
295
+ if (latest) {
296
+ console.log(`last cycle ${latest.cycleId}: ${latest.runsSeen} runs, failedRate ${latest.failedRate}, steerRate ${latest.steerRate}, mergeConflictRate ${latest.mergeConflictRate}`);
297
+ }
298
+ const shipped = ledger.filter((entry) => entry.status === "shipped");
299
+ const open = ledger.filter((entry) => entry.status === "branch-pushed");
300
+ console.log(`shipped: ${shipped.length}, branches awaiting review: ${open.length}, ledger entries: ${ledger.length}`);
301
+ for (const entry of ledger.slice(-8)) {
302
+ console.log(` ${entry.ts} [${entry.status}] ${entry.title}${entry.version ? ` (${entry.version})` : ""}`);
303
+ }
304
+ }
305
+ async function printReport(date) {
306
+ let file;
307
+ try {
308
+ const entries = (await fs.readdir(reportsDir())).filter((name) => name.endsWith(".md")).sort();
309
+ file = date ? entries.find((name) => name.startsWith(date)) : entries.at(-1);
310
+ }
311
+ catch {
312
+ file = undefined;
313
+ }
314
+ if (!file) {
315
+ console.log("improve: no cycle reports yet. Run `rudder improve run`.");
316
+ return;
317
+ }
318
+ console.log(await fs.readFile(path.join(reportsDir(), file), "utf8"));
319
+ }
320
+ /**
321
+ * Find the rudder checkout to improve: an explicit config path wins; else the
322
+ * current repo when it is a rudder checkout; else a registered project whose
323
+ * package.json says @viraatdas/rudder.
324
+ */
325
+ async function resolveRudderRepo() {
326
+ const isRudder = async (dir) => (await readJson(path.join(dir, "package.json")))?.name === "@viraatdas/rudder";
327
+ const root = findRepoRoot(process.cwd());
328
+ if (root && (await isRudder(root)))
329
+ return root;
330
+ for (const project of await loadProjects()) {
331
+ if (project.repoRoot && (await isRudder(project.repoRoot)))
332
+ return project.repoRoot;
333
+ }
334
+ return process.cwd();
335
+ }
336
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/improve/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type GateResult } from "./gate.js";
2
+ import type { SpendMeter } from "./state.js";
3
+ import type { Proposal } from "./propose.js";
4
+ export type JudgeVote = {
5
+ lens: string;
6
+ verdict: "approve" | "reject";
7
+ regression: boolean;
8
+ notes: string;
9
+ };
10
+ export type JudgePanelResult = {
11
+ ship: boolean;
12
+ votes: JudgeVote[];
13
+ };
14
+ export declare function judgePanel(params: {
15
+ proposal: Proposal;
16
+ gate: GateResult;
17
+ model: string;
18
+ advisorModel: string;
19
+ meter: SpendMeter;
20
+ }): Promise<JudgePanelResult>;
21
+ export declare function parseVote(lens: string, output: string): JudgeVote;
22
+ export declare function panelSummary(panel: JudgePanelResult): string;
@@ -0,0 +1,101 @@
1
+ import { callAdvisedTextModel } from "./advisor.js";
2
+ import { gateSummary } from "./gate.js";
3
+ /**
4
+ * Three judges with distinct lenses, each prompted to REFUTE the change. A
5
+ * proposal ships only when no judge flags a regression and a majority
6
+ * approves. (The blind A/B eval-replay tier from the design doc arrives with
7
+ * the eval corpus; until then the panel judges the diff adversarially.)
8
+ */
9
+ const LENSES = [
10
+ {
11
+ lens: "correctness",
12
+ charge: "Does this diff actually address the finding at its root cause? Look for fixes that only paper over symptoms, dead code paths, or changes that cannot affect the reported behavior.",
13
+ },
14
+ {
15
+ lens: "regression-risk",
16
+ charge: "What else could this diff break? Hunt for violated invariants (atomic writes, signal wiring, scheduler locks, parity fixtures), changed behavior outside the finding's scope, and missing test coverage for the risky part.",
17
+ },
18
+ {
19
+ lens: "simplicity",
20
+ charge: "Is there a materially smaller or more conventional change that achieves the same fix? Flag scope creep, new dependencies, gratuitous refactors, and style that fights the surrounding code.",
21
+ },
22
+ ];
23
+ const JUDGE_SYSTEM = `You are one judge on the review panel of Rudder's continual improvement loop. An autonomous agent proposed a diff against the rudder repo to fix a telemetry-mined finding. Your default stance is skeptical: try to refute the change. Deterministic gates (typecheck + test suites) already passed; your job is what tests cannot see.
24
+ Return exactly one fenced json block: {"verdict": "approve" | "reject", "regression": true | false, "notes": "2-4 sentences"}.
25
+ Set regression=true when you can articulate a concrete way this diff makes Rudder worse for users, not for hypothetical style concerns.`;
26
+ export async function judgePanel(params) {
27
+ const { proposal } = params;
28
+ const user = [
29
+ `FINDING: [${proposal.finding.class}, severity ${proposal.finding.severity}/5] ${proposal.finding.title}`,
30
+ proposal.finding.detail,
31
+ "",
32
+ `AGENT'S OWN SUMMARY: ${proposal.resultNote?.summary ?? "(none provided)"}`,
33
+ `AGENT'S SELF-DECLARED RISKS: ${proposal.resultNote?.risks ?? "(none provided)"}`,
34
+ `GATES: ${gateSummary(params.gate)}`,
35
+ "",
36
+ `DIFF STAT:\n${proposal.diffStat}`,
37
+ "",
38
+ `FULL DIFF:\n${proposal.diffText}`,
39
+ ].join("\n");
40
+ const votes = [];
41
+ for (const { lens, charge } of LENSES) {
42
+ if (!params.meter.canAfford(0.15)) {
43
+ // Out of budget mid-panel: fail closed. An unjudged change never ships.
44
+ votes.push({ lens, verdict: "reject", regression: false, notes: "budget exhausted before this vote" });
45
+ continue;
46
+ }
47
+ const system = `${JUDGE_SYSTEM}\n\nYOUR LENS: ${lens}. ${charge}`;
48
+ let output = "";
49
+ try {
50
+ output = await callAdvisedTextModel({
51
+ executorModel: params.model,
52
+ advisorModel: params.advisorModel,
53
+ system,
54
+ user,
55
+ maxTokens: 1024,
56
+ timeoutMs: 240000,
57
+ meter: params.meter,
58
+ });
59
+ }
60
+ catch (error) {
61
+ votes.push({ lens, verdict: "reject", regression: false, notes: `judge call failed: ${String(error)}` });
62
+ continue;
63
+ }
64
+ votes.push(parseVote(lens, output));
65
+ }
66
+ const anyRegression = votes.some((vote) => vote.regression);
67
+ const approvals = votes.filter((vote) => vote.verdict === "approve").length;
68
+ return { ship: !anyRegression && approvals >= 2, votes };
69
+ }
70
+ export function parseVote(lens, output) {
71
+ const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/);
72
+ const candidates = [fenced?.[1], output];
73
+ for (const candidate of candidates) {
74
+ if (!candidate)
75
+ continue;
76
+ const start = candidate.indexOf("{");
77
+ const end = candidate.lastIndexOf("}");
78
+ if (start < 0 || end <= start)
79
+ continue;
80
+ try {
81
+ const value = JSON.parse(candidate.slice(start, end + 1));
82
+ return {
83
+ lens,
84
+ verdict: value.verdict === "approve" ? "approve" : "reject",
85
+ regression: value.regression === true,
86
+ notes: String(value.notes ?? "").slice(0, 600),
87
+ };
88
+ }
89
+ catch {
90
+ // try next candidate
91
+ }
92
+ }
93
+ // Unparseable output fails closed.
94
+ return { lens, verdict: "reject", regression: false, notes: "unparseable judge output" };
95
+ }
96
+ export function panelSummary(panel) {
97
+ return panel.votes
98
+ .map((vote) => `${vote.lens}=${vote.verdict}${vote.regression ? "(regression)" : ""}`)
99
+ .join(", ");
100
+ }
101
+ //# sourceMappingURL=judge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"judge.js","sourceRoot":"","sources":["../../src/improve/judge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { type Finding, type LedgerEntry, type MetricsSnapshot, type SessionRecord, type SpendMeter } from "./state.js";
2
+ /**
3
+ * A condensed surface map so the miner proposes real file paths instead of
4
+ * hallucinated ones. Keep in sync with AGENTS.md section 2 when the layout
5
+ * moves.
6
+ */
7
+ export declare const SURFACE_MAP = "Rudder surface map (repo-relative paths):\n- src/run-manager.ts run lifecycle: start, worker, merge/sync routing\n- src/backends.ts claude/codex/acpx adapters, spawn + event streaming\n- src/brain.ts worker spec/contract rendering, verifyRun\n- src/planner.ts headless DAG planner + plan block parsing\n- src/scheduler.ts headless DAG scheduler (daemon), merge serialization\n- src/jj.ts jj workspace create/merge/rebase/undo substrate\n- src/state.ts run records, config, projects registry persistence\n- src/surfaces.ts DECISIONS.md / completion notes / shared context\n- src/board/daemon.ts web board HTTP+SSE server\n- src/cloud.ts Rudder Cloud client\n- native/src/main.rs Rust TUI: App state machine, poll loop, scheduling\n- native/src/tasks.rs prompt construction, orchestrator system prompt\n- native/src/launch.rs agent launch/resume command building\n- native/src/signals.rs completion signal hooks (Stop hook / notify)\n- native/src/detect.rs idle/permission output heuristics (fallback only)\n- native/src/render.rs TUI rendering";
8
+ export declare function mineFindings(params: {
9
+ cycleId: string;
10
+ sessions: SessionRecord[];
11
+ snapshot: MetricsSnapshot;
12
+ ledger: LedgerEntry[];
13
+ model: string;
14
+ advisorModel: string;
15
+ meter: SpendMeter;
16
+ }): Promise<Finding[]>;
17
+ export declare function frictionScore(session: SessionRecord): number;
18
+ /** Parse the model's findings array out of a fenced block or bare JSON. */
19
+ export declare function parseFindingsJson(output: string): Array<Record<string, unknown>>;
20
+ /**
21
+ * Drop findings the ledger already knows: anything shipped or currently
22
+ * banked under the same title key, and anything previously rejected unless
23
+ * its frequency has at least doubled since the rejection was recorded.
24
+ */
25
+ export declare function dedupeAgainstLedger(findings: Finding[], ledger: LedgerEntry[]): Finding[];