@viraatdas/rudder 2.10.22 → 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 (42) hide show
  1. package/README.md +41 -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/task-summary.d.ts +6 -0
  38. package/dist/task-summary.js +6 -1
  39. package/dist/task-summary.js.map +1 -1
  40. package/dist/types.d.ts +15 -0
  41. package/dist/types.js.map +1 -1
  42. package/package.json +1 -1
@@ -0,0 +1,82 @@
1
+ import { runCommand } from "../util.js";
2
+ import { execStep, tail } from "./state.js";
3
+ const MINUTE = 60 * 1000;
4
+ /**
5
+ * Ship a judged proposal. In `ship` autonomy this follows the repo release
6
+ * rule end to end: rebase onto the latest origin/main, re-typecheck, `npm
7
+ * version patch` (commit + tag vX.Y.Z), and push commit + tag together so the
8
+ * tag-driven release workflow publishes to npm. Non-force push: if main moved
9
+ * between the rebase and the push, this fails cleanly and is recorded as a
10
+ * push-conflict for the next cycle. In `propose` autonomy only the branch is
11
+ * pushed for human review.
12
+ */
13
+ export async function shipProposal(params) {
14
+ const { settings, proposal } = params;
15
+ const cwd = proposal.worktree;
16
+ await assertAllowedRemote(settings);
17
+ if (settings.autonomy === "propose") {
18
+ const push = await runCommand("git", ["push", "-u", "origin", proposal.branch], {
19
+ cwd,
20
+ allowFailure: true,
21
+ });
22
+ if (push.code !== 0) {
23
+ return { status: "push-conflict", detail: tail(push.stderr || push.stdout, 800) };
24
+ }
25
+ return { status: "branch-pushed", branch: proposal.branch };
26
+ }
27
+ // Rebase onto the freshest main so the version bump reads the latest
28
+ // package.json (two winners in one cycle ship sequentially through here).
29
+ const fetch = await runCommand("git", ["fetch", "origin", "main"], { cwd, allowFailure: true });
30
+ if (fetch.code !== 0) {
31
+ return { status: "push-conflict", detail: `fetch failed: ${tail(fetch.stderr, 400)}` };
32
+ }
33
+ const rebase = await runCommand("git", ["rebase", "origin/main"], { cwd, allowFailure: true });
34
+ if (rebase.code !== 0) {
35
+ await runCommand("git", ["rebase", "--abort"], { cwd, allowFailure: true });
36
+ return { status: "push-conflict", detail: `rebase onto origin/main failed: ${tail(rebase.stderr, 800)}` };
37
+ }
38
+ // Cheap re-gate after the rebase; the full suites already passed pre-judge.
39
+ const recheck = await execStep({
40
+ command: "npm",
41
+ args: ["run", "check"],
42
+ cwd,
43
+ timeoutMs: 10 * MINUTE,
44
+ });
45
+ if (recheck.code !== 0) {
46
+ return { status: "push-conflict", detail: `post-rebase typecheck failed: ${tail(recheck.output, 800)}` };
47
+ }
48
+ const version = await runCommand("npm", ["version", "patch", "-m", `improve: ${proposal.finding.title} (v%s)`], { cwd, allowFailure: true });
49
+ if (version.code !== 0) {
50
+ return { status: "push-conflict", detail: `npm version patch failed: ${tail(version.stderr || version.stdout, 800)}` };
51
+ }
52
+ const tag = version.stdout.trim().split("\n").at(-1)?.trim() ?? "";
53
+ if (!/^v\d+\.\d+\.\d+$/.test(tag)) {
54
+ return { status: "push-conflict", detail: `unexpected npm version output: ${tail(version.stdout, 200)}` };
55
+ }
56
+ const push = await runCommand("git", ["push", "origin", `HEAD:main`, `refs/tags/${tag}`], {
57
+ cwd,
58
+ allowFailure: true,
59
+ });
60
+ if (push.code !== 0) {
61
+ // Undo the local tag so a retry next cycle does not collide with it.
62
+ await runCommand("git", ["tag", "-d", tag], { cwd, allowFailure: true });
63
+ return { status: "push-conflict", detail: `push failed: ${tail(push.stderr || push.stdout, 800)}` };
64
+ }
65
+ return { status: "shipped", version: tag };
66
+ }
67
+ /**
68
+ * The ship stage refuses to push anywhere but the configured rudder remote.
69
+ * This is the guard that keeps an unattended loop from ever pushing another
70
+ * project.
71
+ */
72
+ async function assertAllowedRemote(settings) {
73
+ const remote = await runCommand("git", ["remote", "get-url", "origin"], {
74
+ cwd: settings.repoPath,
75
+ allowFailure: true,
76
+ });
77
+ const url = remote.stdout.trim();
78
+ if (remote.code !== 0 || !url.includes(settings.allowedRemote)) {
79
+ throw new Error(`refusing to ship: origin (${url || "missing"}) does not match improve.allowedRemote (${settings.allowedRemote})`);
80
+ }
81
+ }
82
+ //# sourceMappingURL=ship.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ship.js","sourceRoot":"","sources":["../../src/improve/ship.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,149 @@
1
+ import type { RudderConfig } from "../types.js";
2
+ export declare function improveHome(): string;
3
+ export declare function watermarkPath(): string;
4
+ export declare function metricsPath(): string;
5
+ export declare function ledgerPath(): string;
6
+ export declare function reportsDir(): string;
7
+ export declare function logsDir(): string;
8
+ export declare function worktreesDir(): string;
9
+ export declare function cycleLockDir(): string;
10
+ export type ImproveAutonomy = "observe" | "propose" | "ship";
11
+ export type ImproveSettings = {
12
+ enabled: boolean;
13
+ autonomy: ImproveAutonomy;
14
+ budgetUsd: number;
15
+ maxFindings: number;
16
+ /** The rudder checkout the loop improves. */
17
+ repoPath: string;
18
+ /** Remote slug guard: ship only when `origin` matches. */
19
+ allowedRemote: string;
20
+ excludeProjects: string[];
21
+ minerModel: string;
22
+ judgeModel: string;
23
+ /**
24
+ * Advisor tool model for mining/judging calls (Anthropic advisor pattern:
25
+ * cheap executor + high-intelligence advisor). Empty string disables.
26
+ */
27
+ advisorModel: string;
28
+ /** Model passed to the improvement agent CLI; empty = CLI default. */
29
+ workerModel: string;
30
+ agentTimeoutMs: number;
31
+ };
32
+ export declare const IMPROVE_DEFAULTS: {
33
+ autonomy: ImproveAutonomy;
34
+ budgetUsd: number;
35
+ maxFindings: number;
36
+ allowedRemote: string;
37
+ minerModel: string;
38
+ judgeModel: string;
39
+ advisorModel: string;
40
+ agentTimeoutMs: number;
41
+ };
42
+ export declare function resolveImproveSettings(config: RudderConfig, repoFallback: string): ImproveSettings;
43
+ export type SessionRecord = {
44
+ project: string;
45
+ repoRoot: string;
46
+ runId: string;
47
+ task: string;
48
+ backend: string;
49
+ model?: string;
50
+ effort?: string;
51
+ status: string;
52
+ createdAt: string;
53
+ updatedAt: string;
54
+ durationMs?: number;
55
+ steerCount: number;
56
+ autoSteerCount: number;
57
+ tokensIn: number;
58
+ tokensOut: number;
59
+ verifierSatisfied?: boolean;
60
+ verifierMissing?: string[];
61
+ mergeStatus?: string;
62
+ errorExcerpts: string[];
63
+ };
64
+ export type MetricsSnapshot = {
65
+ ts: string;
66
+ cycleId: string;
67
+ runsSeen: number;
68
+ failedRate: number;
69
+ cancelledRate: number;
70
+ steerRate: number;
71
+ mergeConflictRate: number;
72
+ verifierMissRate: number;
73
+ medianDurationMs: number;
74
+ totalTokensIn: number;
75
+ totalTokensOut: number;
76
+ };
77
+ export type FindingClass = "prompt" | "orchestration" | "ux" | "perf" | "crash" | "other";
78
+ export type Finding = {
79
+ id: string;
80
+ class: FindingClass;
81
+ title: string;
82
+ detail: string;
83
+ evidence: Array<{
84
+ project: string;
85
+ runId: string;
86
+ excerpt: string;
87
+ }>;
88
+ severity: number;
89
+ frequency: number;
90
+ suspectedSurfaces: string[];
91
+ score?: number;
92
+ };
93
+ export type LedgerStatus = "reported" | "banked" | "agent-failed" | "gated-out" | "judge-rejected" | "branch-pushed" | "push-conflict" | "shipped" | "outcome";
94
+ export type LedgerEntry = {
95
+ ts: string;
96
+ cycleId: string;
97
+ findingId: string;
98
+ titleKey: string;
99
+ title: string;
100
+ class: string;
101
+ status: LedgerStatus;
102
+ detail?: string;
103
+ version?: string;
104
+ branch?: string;
105
+ targetMetric?: string;
106
+ metricAtShip?: number;
107
+ outcome?: "confirmed" | "no-effect" | "regressed";
108
+ };
109
+ export declare function titleKey(title: string): string;
110
+ export declare function appendJsonl(filePath: string, value: unknown): Promise<void>;
111
+ export declare function readJsonl<T>(filePath: string): Promise<T[]>;
112
+ export type Watermark = {
113
+ version: 1;
114
+ projects: Record<string, string>;
115
+ };
116
+ export declare function loadWatermark(): Promise<Watermark>;
117
+ export declare function saveWatermark(mark: Watermark): Promise<void>;
118
+ export declare function acquireCycleLock(): Promise<boolean>;
119
+ export declare function releaseCycleLock(): Promise<void>;
120
+ export declare const AGENT_RUN_FLAT_USD = 0.75;
121
+ export declare class SpendMeter {
122
+ private readonly budgetUsd;
123
+ private spent;
124
+ constructor(budgetUsd: number);
125
+ addModelCall(model: string, inChars: number, outChars: number): void;
126
+ /** Exact token accounting (used when the API reports usage.iterations). */
127
+ addModelTokens(model: string, inputTokens: number, outputTokens: number): void;
128
+ addFlat(usd: number): void;
129
+ spentUsd(): number;
130
+ remainingUsd(): number;
131
+ /** True when there is room for at least `usd` more estimated spend. */
132
+ canAfford(usd: number): boolean;
133
+ }
134
+ export type StepResult = {
135
+ code: number;
136
+ timedOut: boolean;
137
+ output: string;
138
+ };
139
+ export declare function execStep(params: {
140
+ command: string;
141
+ args: string[];
142
+ cwd: string;
143
+ timeoutMs: number;
144
+ stdin?: string;
145
+ env?: NodeJS.ProcessEnv;
146
+ logFile?: string;
147
+ }): Promise<StepResult>;
148
+ export declare function tail(text: string, maxChars: number): string;
149
+ export declare function fileExists(filePath: string): Promise<boolean>;
@@ -0,0 +1,261 @@
1
+ import path from "node:path";
2
+ import { promises as fs } from "node:fs";
3
+ import { spawn } from "node:child_process";
4
+ import { commandEnv, ensureDir, pathExists, readJson, rudderHome, writeJson } from "../util.js";
5
+ // ---------------------------------------------------------------------------
6
+ // The continual improvement loop's on-disk state lives under ~/.rudder/improve.
7
+ // Everything here is append-only JSONL or atomic JSON via writeJson, matching
8
+ // the repo persistence conventions. See docs/continual-improvement.md.
9
+ // ---------------------------------------------------------------------------
10
+ export function improveHome() {
11
+ return path.join(rudderHome(), "improve");
12
+ }
13
+ export function watermarkPath() {
14
+ return path.join(improveHome(), "watermark.json");
15
+ }
16
+ export function metricsPath() {
17
+ return path.join(improveHome(), "metrics.jsonl");
18
+ }
19
+ export function ledgerPath() {
20
+ return path.join(improveHome(), "ledger.jsonl");
21
+ }
22
+ export function reportsDir() {
23
+ return path.join(improveHome(), "reports");
24
+ }
25
+ export function logsDir() {
26
+ return path.join(improveHome(), "logs");
27
+ }
28
+ export function worktreesDir() {
29
+ return path.join(improveHome(), "worktrees");
30
+ }
31
+ export function cycleLockDir() {
32
+ return path.join(improveHome(), "cycle.lock");
33
+ }
34
+ export const IMPROVE_DEFAULTS = {
35
+ autonomy: "ship",
36
+ budgetUsd: 5,
37
+ maxFindings: 3,
38
+ allowedRemote: "viraatdas/rudder",
39
+ minerModel: "claude-sonnet-4-6",
40
+ judgeModel: "claude-sonnet-4-6",
41
+ advisorModel: "claude-fable-5",
42
+ agentTimeoutMs: 25 * 60 * 1000,
43
+ };
44
+ export function resolveImproveSettings(config, repoFallback) {
45
+ const raw = config.improve ?? {};
46
+ const envDisabled = process.env.RUDDER_IMPROVE === "0";
47
+ return {
48
+ enabled: !envDisabled && raw.enabled !== false,
49
+ autonomy: raw.autonomy ?? IMPROVE_DEFAULTS.autonomy,
50
+ budgetUsd: raw.budgetUsd ?? IMPROVE_DEFAULTS.budgetUsd,
51
+ maxFindings: raw.maxFindings ?? IMPROVE_DEFAULTS.maxFindings,
52
+ repoPath: raw.repoPath ?? repoFallback,
53
+ allowedRemote: raw.allowedRemote ?? IMPROVE_DEFAULTS.allowedRemote,
54
+ excludeProjects: raw.excludeProjects ?? [],
55
+ minerModel: raw.minerModel ?? IMPROVE_DEFAULTS.minerModel,
56
+ judgeModel: raw.judgeModel ?? IMPROVE_DEFAULTS.judgeModel,
57
+ advisorModel: raw.advisorModel ?? IMPROVE_DEFAULTS.advisorModel,
58
+ workerModel: raw.workerModel ?? "",
59
+ agentTimeoutMs: raw.agentTimeoutMs ?? IMPROVE_DEFAULTS.agentTimeoutMs,
60
+ };
61
+ }
62
+ export function titleKey(title) {
63
+ return title
64
+ .toLowerCase()
65
+ .replace(/[^a-z0-9 ]+/g, "")
66
+ .split(/\s+/)
67
+ .filter(Boolean)
68
+ .slice(0, 8)
69
+ .join("-");
70
+ }
71
+ // ---------------------------------------------------------------------------
72
+ // JSONL helpers
73
+ // ---------------------------------------------------------------------------
74
+ export async function appendJsonl(filePath, value) {
75
+ await ensureDir(path.dirname(filePath));
76
+ await fs.appendFile(filePath, `${JSON.stringify(value)}\n`, "utf8");
77
+ }
78
+ export async function readJsonl(filePath) {
79
+ try {
80
+ const raw = await fs.readFile(filePath, "utf8");
81
+ const out = [];
82
+ for (const line of raw.split("\n")) {
83
+ const trimmed = line.trim();
84
+ if (!trimmed)
85
+ continue;
86
+ try {
87
+ out.push(JSON.parse(trimmed));
88
+ }
89
+ catch {
90
+ // skip torn/corrupt lines; the files are append-only diagnostics
91
+ }
92
+ }
93
+ return out;
94
+ }
95
+ catch {
96
+ return [];
97
+ }
98
+ }
99
+ export async function loadWatermark() {
100
+ const existing = await readJson(watermarkPath());
101
+ if (existing?.version === 1 && existing.projects) {
102
+ return existing;
103
+ }
104
+ return { version: 1, projects: {} };
105
+ }
106
+ export async function saveWatermark(mark) {
107
+ await ensureDir(improveHome());
108
+ await writeJson(watermarkPath(), mark);
109
+ }
110
+ // ---------------------------------------------------------------------------
111
+ // Single-instance cycle lock (mkdir lock, stale takeover), the same shape as
112
+ // .rudder/integrate.lock. Not reentrant.
113
+ // ---------------------------------------------------------------------------
114
+ const LOCK_STALE_MS = 6 * 60 * 60 * 1000;
115
+ export async function acquireCycleLock() {
116
+ await ensureDir(improveHome());
117
+ const lock = cycleLockDir();
118
+ try {
119
+ await fs.mkdir(lock);
120
+ await fs.writeFile(path.join(lock, "pid"), String(process.pid), "utf8");
121
+ return true;
122
+ }
123
+ catch {
124
+ try {
125
+ const stat = await fs.stat(lock);
126
+ if (Date.now() - stat.mtimeMs > LOCK_STALE_MS) {
127
+ await fs.rm(lock, { recursive: true, force: true });
128
+ await fs.mkdir(lock);
129
+ await fs.writeFile(path.join(lock, "pid"), String(process.pid), "utf8");
130
+ return true;
131
+ }
132
+ }
133
+ catch {
134
+ // fall through: someone else holds it
135
+ }
136
+ return false;
137
+ }
138
+ }
139
+ export async function releaseCycleLock() {
140
+ await fs.rm(cycleLockDir(), { recursive: true, force: true });
141
+ }
142
+ // ---------------------------------------------------------------------------
143
+ // Spend meter: a coarse budget guardrail, not accounting. Model calls are
144
+ // estimated at chars/4 tokens against a small price table; agent runs are a
145
+ // flat estimate because the CLI's own auth (subscription) hides real cost.
146
+ // ---------------------------------------------------------------------------
147
+ const PRICE_PER_MTOK = [
148
+ { match: /haiku/i, inUsd: 1, outUsd: 5 },
149
+ { match: /sonnet/i, inUsd: 3, outUsd: 15 },
150
+ { match: /opus|fable/i, inUsd: 5, outUsd: 25 },
151
+ ];
152
+ export const AGENT_RUN_FLAT_USD = 0.75;
153
+ export class SpendMeter {
154
+ budgetUsd;
155
+ spent = 0;
156
+ constructor(budgetUsd) {
157
+ this.budgetUsd = budgetUsd;
158
+ }
159
+ addModelCall(model, inChars, outChars) {
160
+ this.addModelTokens(model, inChars / 4, outChars / 4);
161
+ }
162
+ /** Exact token accounting (used when the API reports usage.iterations). */
163
+ addModelTokens(model, inputTokens, outputTokens) {
164
+ const price = PRICE_PER_MTOK.find((p) => p.match.test(model)) ?? PRICE_PER_MTOK[1];
165
+ this.spent += (inputTokens / 1_000_000) * price.inUsd + (outputTokens / 1_000_000) * price.outUsd;
166
+ }
167
+ addFlat(usd) {
168
+ this.spent += usd;
169
+ }
170
+ spentUsd() {
171
+ return this.spent;
172
+ }
173
+ remainingUsd() {
174
+ return Math.max(0, this.budgetUsd - this.spent);
175
+ }
176
+ /** True when there is room for at least `usd` more estimated spend. */
177
+ canAfford(usd) {
178
+ return this.spent + usd <= this.budgetUsd;
179
+ }
180
+ }
181
+ export async function execStep(params) {
182
+ return await new Promise((resolve) => {
183
+ let settled = false;
184
+ let timedOut = false;
185
+ let output = "";
186
+ const finish = (code) => {
187
+ if (settled)
188
+ return;
189
+ settled = true;
190
+ if (params.logFile) {
191
+ void ensureDir(path.dirname(params.logFile)).then(() => fs.appendFile(params.logFile, `\n===== ${params.command} ${params.args.join(" ")} (exit ${code}${timedOut ? ", timed out" : ""}) =====\n${output}`, "utf8"));
192
+ }
193
+ resolve({ code, timedOut, output });
194
+ };
195
+ let child;
196
+ try {
197
+ child = spawn(params.command, params.args, {
198
+ cwd: params.cwd,
199
+ env: commandEnv(params.env),
200
+ stdio: [params.stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"],
201
+ });
202
+ }
203
+ catch (error) {
204
+ output = String(error);
205
+ finish(127);
206
+ return;
207
+ }
208
+ const timer = setTimeout(() => {
209
+ timedOut = true;
210
+ try {
211
+ child.kill("SIGTERM");
212
+ setTimeout(() => {
213
+ try {
214
+ child.kill("SIGKILL");
215
+ }
216
+ catch {
217
+ // already gone
218
+ }
219
+ }, 5000).unref();
220
+ }
221
+ catch {
222
+ // already gone
223
+ }
224
+ }, params.timeoutMs);
225
+ child.stdout?.setEncoding("utf8");
226
+ child.stderr?.setEncoding("utf8");
227
+ child.stdout?.on("data", (chunk) => {
228
+ output += chunk;
229
+ });
230
+ child.stderr?.on("data", (chunk) => {
231
+ output += chunk;
232
+ });
233
+ child.on("error", (error) => {
234
+ clearTimeout(timer);
235
+ output += `\n${String(error)}`;
236
+ finish(127);
237
+ });
238
+ child.on("close", (code) => {
239
+ clearTimeout(timer);
240
+ finish(timedOut ? 124 : (code ?? 1));
241
+ });
242
+ if (params.stdin !== undefined) {
243
+ try {
244
+ child.stdin?.write(params.stdin);
245
+ child.stdin?.end();
246
+ }
247
+ catch {
248
+ // child error handler will fire
249
+ }
250
+ }
251
+ });
252
+ }
253
+ export function tail(text, maxChars) {
254
+ if (text.length <= maxChars)
255
+ return text;
256
+ return `…${text.slice(text.length - maxChars)}`;
257
+ }
258
+ export async function fileExists(filePath) {
259
+ return await pathExists(filePath);
260
+ }
261
+ //# sourceMappingURL=state.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/improve/state.ts"],"names":[],"mappings":"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"}
package/dist/main.js CHANGED
@@ -236,6 +236,11 @@ export async function main() {
236
236
  case "gc":
237
237
  await runGc({ dryRun: Boolean(parsed.flags.dryRun) });
238
238
  return;
239
+ case "improve": {
240
+ const { runImprove } = await import("./improve/index.js");
241
+ await runImprove(parsed);
242
+ return;
243
+ }
239
244
  case "board":
240
245
  case "serve": {
241
246
  await runBoard(parsed);
@@ -924,6 +929,12 @@ Run management:
924
929
  rudder gc [--dry-run] Prune bounded diagnostics, old binaries, and stale run records
925
930
  rudder undo [opId] Rewind jj to an op id, or the last undo-stack entry (global)
926
931
 
932
+ Improvement loop:
933
+ rudder improve run [--dry-run] [--budget-usd N] Mine telemetry, propose+judge fixes, ship a release
934
+ rudder improve status Last cycle, shipped versions, ledger tail
935
+ rudder improve report [date] Print a cycle report
936
+ rudder improve schedule install|uninstall|status Nightly launchd schedule (macOS)
937
+
927
938
  Planner:
928
939
  rudder plan "task" Decompose a task into a DAG, scaffold empty jj changes, write graph.json
929
940
  rudder fanout "task" [--n N] Fan out N variant agents on one task, then a judge picks/merges the best (default N=3)