ralph-research 0.1.0 → 0.1.2

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 (90) hide show
  1. package/README.md +69 -0
  2. package/dist/adapters/extractor/command-extractor.js +46 -4
  3. package/dist/adapters/extractor/command-extractor.js.map +1 -1
  4. package/dist/adapters/fs/json-file-frontier-store.js +4 -2
  5. package/dist/adapters/fs/json-file-frontier-store.js.map +1 -1
  6. package/dist/adapters/fs/lockfile.d.ts +21 -1
  7. package/dist/adapters/fs/lockfile.js +65 -11
  8. package/dist/adapters/fs/lockfile.js.map +1 -1
  9. package/dist/adapters/fs/manifest-loader.d.ts +5 -1
  10. package/dist/adapters/fs/manifest-loader.js +15 -2
  11. package/dist/adapters/fs/manifest-loader.js.map +1 -1
  12. package/dist/adapters/git/git-client.d.ts +2 -0
  13. package/dist/adapters/git/git-client.js +19 -0
  14. package/dist/adapters/git/git-client.js.map +1 -1
  15. package/dist/app/services/manual-decision-service.js +76 -25
  16. package/dist/app/services/manual-decision-service.js.map +1 -1
  17. package/dist/app/services/project-state-service.d.ts +26 -1
  18. package/dist/app/services/project-state-service.js +172 -14
  19. package/dist/app/services/project-state-service.js.map +1 -1
  20. package/dist/app/services/run-admission-service.d.ts +20 -0
  21. package/dist/app/services/run-admission-service.js +30 -0
  22. package/dist/app/services/run-admission-service.js.map +1 -0
  23. package/dist/app/services/run-cycle-service.d.ts +5 -4
  24. package/dist/app/services/run-cycle-service.js +175 -14
  25. package/dist/app/services/run-cycle-service.js.map +1 -1
  26. package/dist/app/services/run-loop-service.d.ts +21 -0
  27. package/dist/app/services/run-loop-service.js +155 -0
  28. package/dist/app/services/run-loop-service.js.map +1 -0
  29. package/dist/cli/commands/demo.js +1 -0
  30. package/dist/cli/commands/demo.js.map +1 -1
  31. package/dist/cli/commands/doctor.d.ts +8 -0
  32. package/dist/cli/commands/doctor.js +59 -0
  33. package/dist/cli/commands/doctor.js.map +1 -0
  34. package/dist/cli/commands/init.js +1 -0
  35. package/dist/cli/commands/init.js.map +1 -1
  36. package/dist/cli/commands/inspect.js +4 -0
  37. package/dist/cli/commands/inspect.js.map +1 -1
  38. package/dist/cli/commands/run.d.ts +3 -1
  39. package/dist/cli/commands/run.js +31 -28
  40. package/dist/cli/commands/run.js.map +1 -1
  41. package/dist/cli/commands/status.js +35 -4
  42. package/dist/cli/commands/status.js.map +1 -1
  43. package/dist/cli/commands/validate.js +21 -18
  44. package/dist/cli/commands/validate.js.map +1 -1
  45. package/dist/cli/main.js +3 -10
  46. package/dist/cli/main.js.map +1 -1
  47. package/dist/core/engine/cycle-runner.d.ts +2 -0
  48. package/dist/core/engine/cycle-runner.js +504 -34
  49. package/dist/core/engine/cycle-runner.js.map +1 -1
  50. package/dist/core/engine/promotion-artifact.d.ts +23 -0
  51. package/dist/core/engine/promotion-artifact.js +58 -0
  52. package/dist/core/engine/promotion-artifact.js.map +1 -0
  53. package/dist/core/engine/workspace-manager.d.ts +10 -1
  54. package/dist/core/engine/workspace-manager.js +70 -3
  55. package/dist/core/engine/workspace-manager.js.map +1 -1
  56. package/dist/core/manifest/admission.d.ts +16 -0
  57. package/dist/core/manifest/admission.js +64 -0
  58. package/dist/core/manifest/admission.js.map +1 -0
  59. package/dist/core/manifest/schema.d.ts +47 -0
  60. package/dist/core/manifest/schema.js +18 -1
  61. package/dist/core/manifest/schema.js.map +1 -1
  62. package/dist/core/model/decision-record.d.ts +4 -0
  63. package/dist/core/model/decision-record.js +6 -0
  64. package/dist/core/model/decision-record.js.map +1 -1
  65. package/dist/core/model/metric-diagnostics.d.ts +7 -0
  66. package/dist/core/model/metric-diagnostics.js +51 -0
  67. package/dist/core/model/metric-diagnostics.js.map +1 -0
  68. package/dist/core/model/run-record.d.ts +6 -0
  69. package/dist/core/model/run-record.js +4 -0
  70. package/dist/core/model/run-record.js.map +1 -1
  71. package/dist/core/state/frontier-materializer.d.ts +12 -0
  72. package/dist/core/state/frontier-materializer.js +74 -0
  73. package/dist/core/state/frontier-materializer.js.map +1 -0
  74. package/dist/core/state/frontier-semantics.d.ts +12 -0
  75. package/dist/core/state/frontier-semantics.js +26 -0
  76. package/dist/core/state/frontier-semantics.js.map +1 -0
  77. package/dist/core/state/ratchet-engine.js +29 -21
  78. package/dist/core/state/ratchet-engine.js.map +1 -1
  79. package/dist/core/state/recovery-classifier.d.ts +17 -0
  80. package/dist/core/state/recovery-classifier.js +150 -0
  81. package/dist/core/state/recovery-classifier.js.map +1 -0
  82. package/dist/core/state/run-state-machine.js +33 -23
  83. package/dist/core/state/run-state-machine.js.map +1 -1
  84. package/dist/core/state/stopping-target.d.ts +14 -0
  85. package/dist/core/state/stopping-target.js +67 -0
  86. package/dist/core/state/stopping-target.js.map +1 -0
  87. package/dist/mcp/server.js +17 -23
  88. package/dist/mcp/server.js.map +1 -1
  89. package/package.json +2 -2
  90. package/templates/writing/ralph.yaml +7 -0
@@ -0,0 +1,150 @@
1
+ export function derivePendingAction(run) {
2
+ switch (run.phase) {
3
+ case "started":
4
+ return "prepare_proposal";
5
+ case "proposed":
6
+ return "execute_experiment";
7
+ case "executed":
8
+ return "evaluate_metrics";
9
+ case "evaluated":
10
+ return "write_decision";
11
+ case "decision_written":
12
+ if (run.status === "accepted") {
13
+ return "commit_candidate";
14
+ }
15
+ if (run.status === "needs_human") {
16
+ return "none";
17
+ }
18
+ return "cleanup_workspace";
19
+ case "committed":
20
+ return "update_frontier";
21
+ case "frontier_updated":
22
+ return "cleanup_workspace";
23
+ case "completed":
24
+ case "failed":
25
+ return "none";
26
+ }
27
+ }
28
+ export function classifyRecovery(input) {
29
+ const run = input.latestRun;
30
+ if (!run) {
31
+ return {
32
+ classification: "idle",
33
+ nextAction: "none",
34
+ reason: "no latest run exists",
35
+ resumeAllowed: false,
36
+ };
37
+ }
38
+ if (run.status === "needs_human") {
39
+ return {
40
+ classification: "manual_review_blocked",
41
+ nextAction: "none",
42
+ reason: "latest run is waiting for manual review",
43
+ resumeAllowed: false,
44
+ };
45
+ }
46
+ if (run.proposal.proposerType === "parallel") {
47
+ return {
48
+ classification: "repair_required",
49
+ nextAction: "none",
50
+ reason: "parallel proposer runs cannot be resumed truthfully yet",
51
+ resumeAllowed: false,
52
+ };
53
+ }
54
+ if (run.phase === "completed") {
55
+ return {
56
+ classification: "idle",
57
+ nextAction: "none",
58
+ reason: "latest run already completed",
59
+ resumeAllowed: false,
60
+ };
61
+ }
62
+ if (run.phase === "failed") {
63
+ return {
64
+ classification: "repair_required",
65
+ nextAction: "none",
66
+ reason: "latest run failed and requires repair before it can be trusted",
67
+ resumeAllowed: false,
68
+ };
69
+ }
70
+ const nextAction = run.pendingAction !== "none"
71
+ ? run.pendingAction
72
+ : derivePendingAction(run);
73
+ const evidenceFailure = findEvidenceFailure(input, nextAction);
74
+ if (evidenceFailure) {
75
+ return {
76
+ classification: "repair_required",
77
+ nextAction: "none",
78
+ reason: evidenceFailure,
79
+ resumeAllowed: false,
80
+ };
81
+ }
82
+ return {
83
+ classification: "resumable",
84
+ nextAction,
85
+ reason: `resume from ${run.phase} via ${nextAction}`,
86
+ resumeAllowed: true,
87
+ };
88
+ }
89
+ function findEvidenceFailure(input, nextAction) {
90
+ const run = input.latestRun;
91
+ if (!run) {
92
+ return "missing latest run";
93
+ }
94
+ switch (run.phase) {
95
+ case "started":
96
+ return null;
97
+ case "proposed":
98
+ if (!run.workspacePath) {
99
+ return "proposal checkpoint is missing a durable workspace path";
100
+ }
101
+ if (run.proposal.summary === "proposal pending") {
102
+ return "proposal checkpoint does not contain a durable proposal result";
103
+ }
104
+ return null;
105
+ case "executed":
106
+ if (!run.workspacePath) {
107
+ return "experiment checkpoint is missing a durable workspace path";
108
+ }
109
+ if (!run.logs.runStdoutPath) {
110
+ return "experiment checkpoint is missing execution logs";
111
+ }
112
+ return null;
113
+ case "evaluated":
114
+ if (Object.keys(run.metrics).length === 0) {
115
+ return "evaluation checkpoint is missing persisted metrics";
116
+ }
117
+ return null;
118
+ case "decision_written":
119
+ if (!run.decisionId) {
120
+ return "decision checkpoint is missing the decision identifier";
121
+ }
122
+ if (run.status === "accepted" && !run.proposal.patchPath) {
123
+ return "accepted decision checkpoint is missing a durable promotion patch";
124
+ }
125
+ if (run.status === "accepted" && nextAction !== "commit_candidate") {
126
+ return "accepted decision checkpoint has an invalid next action";
127
+ }
128
+ return null;
129
+ case "committed":
130
+ if (!run.decisionId) {
131
+ return "commit checkpoint is missing the decision identifier";
132
+ }
133
+ if (!input.decision?.commitSha) {
134
+ return "commit checkpoint is missing a durable commit sha";
135
+ }
136
+ return null;
137
+ case "frontier_updated":
138
+ if (!frontierContainsRun(input.frontier, run.runId)) {
139
+ return "frontier-updated checkpoint is missing persisted frontier membership";
140
+ }
141
+ return null;
142
+ case "completed":
143
+ case "failed":
144
+ return null;
145
+ }
146
+ }
147
+ function frontierContainsRun(frontier, runId) {
148
+ return frontier?.some((entry) => entry.runId === runId) ?? false;
149
+ }
150
+ //# sourceMappingURL=recovery-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recovery-classifier.js","sourceRoot":"","sources":["../../../src/core/state/recovery-classifier.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,7 @@
1
1
  import { pendingActionSchema, runRecordSchema, } from "../model/run-record.js";
2
+ import { classifyRecovery, derivePendingAction } from "./recovery-classifier.js";
2
3
  const phaseOrder = [
4
+ "started",
3
5
  "proposed",
4
6
  "executed",
5
7
  "evaluated",
@@ -16,16 +18,30 @@ export function advanceRunPhase(run, nextPhase, options = {}) {
16
18
  return runRecordSchema.parse(run);
17
19
  }
18
20
  const resolvedPhase = nextIndex === currentIndex ? run.phase : nextPhase;
21
+ const at = options.at ?? new Date().toISOString();
19
22
  const status = options.status ?? inferStatusForPhase(run.status, resolvedPhase);
20
- const pendingAction = options.pendingAction ?? inferPendingAction({ ...run, status, phase: resolvedPhase });
23
+ const pendingAction = options.pendingAction ?? derivePendingAction({ ...run, status, phase: resolvedPhase });
24
+ if (resolvedPhase === run.phase
25
+ && status === run.status
26
+ && pendingAction === run.pendingAction
27
+ && options.decisionId === undefined
28
+ && options.error === undefined
29
+ && options.at === undefined) {
30
+ return runRecordSchema.parse(run);
31
+ }
32
+ const currentStepStartedAt = pendingAction !== run.pendingAction
33
+ ? at
34
+ : run.currentStepStartedAt ?? run.updatedAt ?? run.startedAt;
21
35
  const updated = runRecordSchema.parse({
22
36
  ...run,
23
37
  status,
24
38
  phase: resolvedPhase,
25
39
  pendingAction: pendingActionSchema.parse(pendingAction),
40
+ updatedAt: at,
41
+ currentStepStartedAt,
26
42
  decisionId: options.decisionId ?? run.decisionId,
27
43
  error: options.error ?? run.error,
28
- endedAt: resolvedPhase === "completed" || resolvedPhase === "failed" ? options.at ?? run.endedAt ?? new Date().toISOString() : run.endedAt,
44
+ endedAt: resolvedPhase === "completed" || resolvedPhase === "failed" ? at : run.endedAt,
29
45
  });
30
46
  return updated;
31
47
  }
@@ -33,6 +49,13 @@ export function canResume(run) {
33
49
  return recoverRun(run).resumable;
34
50
  }
35
51
  export function recoverRun(run) {
52
+ if (run.status === "needs_human") {
53
+ return {
54
+ resumable: false,
55
+ nextAction: "none",
56
+ reason: "run is waiting for manual review",
57
+ };
58
+ }
36
59
  if (run.phase === "completed") {
37
60
  return {
38
61
  resumable: false,
@@ -47,15 +70,21 @@ export function recoverRun(run) {
47
70
  reason: "run failed and requires explicit intervention",
48
71
  };
49
72
  }
50
- const nextAction = run.pendingAction !== "none" ? run.pendingAction : inferPendingAction(run);
73
+ const recovery = classifyRecovery({ latestRun: run });
74
+ const nextAction = run.pendingAction !== "none"
75
+ ? run.pendingAction
76
+ : derivePendingAction(run);
51
77
  return {
52
78
  resumable: nextAction !== "none",
53
79
  nextAction,
54
- reason: `resume from phase ${run.phase} with action ${nextAction}`,
80
+ reason: recovery.classification === "repair_required"
81
+ ? `resume from ${run.phase} with action ${nextAction}`
82
+ : recovery.reason,
55
83
  };
56
84
  }
57
85
  function inferStatusForPhase(currentStatus, phase) {
58
86
  switch (phase) {
87
+ case "started":
59
88
  case "proposed":
60
89
  case "executed":
61
90
  return "running";
@@ -72,23 +101,4 @@ function inferStatusForPhase(currentStatus, phase) {
72
101
  return "failed";
73
102
  }
74
103
  }
75
- function inferPendingAction(run) {
76
- switch (run.phase) {
77
- case "proposed":
78
- return "execute_experiment";
79
- case "executed":
80
- return "evaluate_metrics";
81
- case "evaluated":
82
- return "write_decision";
83
- case "decision_written":
84
- return run.status === "accepted" ? "commit_candidate" : "cleanup_workspace";
85
- case "committed":
86
- return "update_frontier";
87
- case "frontier_updated":
88
- return "cleanup_workspace";
89
- case "completed":
90
- case "failed":
91
- return "none";
92
- }
93
- }
94
104
  //# sourceMappingURL=run-state-machine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"run-state-machine.js","sourceRoot":"","sources":["../../../src/core/state/run-state-machine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"run-state-machine.js","sourceRoot":"","sources":["../../../src/core/state/run-state-machine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { ComparisonOperator, RalphManifest } from "../manifest/schema.js";
2
+ import type { FrontierEntry } from "../model/frontier-entry.js";
3
+ import type { MetricResult } from "../model/metric.js";
4
+ export interface StoppingTargetStatus {
5
+ configured: boolean;
6
+ met: boolean;
7
+ metricId?: string;
8
+ op?: ComparisonOperator;
9
+ targetValue?: number;
10
+ currentValue?: number;
11
+ direction?: MetricResult["direction"];
12
+ reason: string;
13
+ }
14
+ export declare function evaluateStoppingTarget(manifest: RalphManifest, frontier: FrontierEntry[]): StoppingTargetStatus;
@@ -0,0 +1,67 @@
1
+ export function evaluateStoppingTarget(manifest, frontier) {
2
+ const target = manifest.stopping.target;
3
+ if (!target) {
4
+ return {
5
+ configured: false,
6
+ met: false,
7
+ reason: "manifest does not define stopping.target",
8
+ };
9
+ }
10
+ const metricId = target.metric ?? getReferenceMetric(manifest);
11
+ const frontierMetrics = frontier
12
+ .map((entry) => entry.metrics[metricId])
13
+ .filter((metric) => Boolean(metric));
14
+ if (frontierMetrics.length === 0) {
15
+ return {
16
+ configured: true,
17
+ met: false,
18
+ metricId,
19
+ op: target.op,
20
+ targetValue: target.value,
21
+ reason: `target ${metricId} ${target.op} ${target.value} is not met because the frontier is empty`,
22
+ };
23
+ }
24
+ const bestMetric = frontierMetrics.reduce((best, current) => {
25
+ if (best.direction !== current.direction) {
26
+ throw new Error(`frontier metric direction mismatch for stopping target ${metricId}`);
27
+ }
28
+ if (best.direction === "maximize") {
29
+ return current.value > best.value ? current : best;
30
+ }
31
+ return current.value < best.value ? current : best;
32
+ });
33
+ const met = compare(bestMetric.value, target.op, target.value);
34
+ return {
35
+ configured: true,
36
+ met,
37
+ metricId,
38
+ op: target.op,
39
+ targetValue: target.value,
40
+ currentValue: bestMetric.value,
41
+ direction: bestMetric.direction,
42
+ reason: met
43
+ ? `target met: ${metricId}=${bestMetric.value} ${target.op} ${target.value}`
44
+ : `target pending: ${metricId}=${bestMetric.value} does not satisfy ${target.op} ${target.value}`,
45
+ };
46
+ }
47
+ function compare(actual, op, expected) {
48
+ switch (op) {
49
+ case ">=":
50
+ return actual >= expected;
51
+ case ">":
52
+ return actual > expected;
53
+ case "<=":
54
+ return actual <= expected;
55
+ case "<":
56
+ return actual < expected;
57
+ case "==":
58
+ return actual === expected;
59
+ }
60
+ }
61
+ function getReferenceMetric(manifest) {
62
+ if (manifest.frontier.strategy === "single_best") {
63
+ return manifest.frontier.primaryMetric;
64
+ }
65
+ return manifest.frontier.objectives[0].metric;
66
+ }
67
+ //# sourceMappingURL=stopping-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stopping-target.js","sourceRoot":"","sources":["../../../src/core/state/stopping-target.ts"],"names":[],"mappings":"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"}
@@ -3,45 +3,39 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
4
  import * as z from "zod/v4";
5
5
  import { getProjectFrontier, getProjectStatus } from "../app/services/project-state-service.js";
6
- import { RunCycleService } from "../app/services/run-cycle-service.js";
6
+ import { RunLoopService } from "../app/services/run-loop-service.js";
7
7
  export function createRalphResearchMcpServer(options = {}) {
8
8
  const defaultRepoRoot = resolve(options.repoRoot ?? process.cwd());
9
9
  const server = new McpServer({
10
10
  name: "ralph-research",
11
- version: "0.1.0",
11
+ version: "0.1.2",
12
12
  });
13
13
  server.registerTool("run_research_cycle", {
14
14
  description: "Run one or more research cycles using the shared ralph-research service layer.",
15
15
  inputSchema: {
16
16
  repoRoot: z.string().optional().describe("Repository root; defaults to the server working directory."),
17
17
  manifestPath: z.string().optional().describe("Optional path to the manifest file."),
18
- cycles: z.number().int().min(1).max(20).default(1).describe("Number of cycles to run."),
19
- resume: z.boolean().default(false).describe("Resume the latest run if it is recoverable."),
18
+ cycles: z.number().int().min(1).max(100).optional().describe("Exact cycle count, or a max-cycle cap when used with progressive stop flags."),
19
+ untilTarget: z.boolean().default(false).describe("Keep running until manifest.stopping.target is met."),
20
+ untilNoImprove: z.number().int().min(1).max(100).optional().describe("Stop after N consecutive cycles without frontier improvement."),
21
+ fresh: z.boolean().default(false).describe("Start a fresh run instead of auto-resuming the latest recoverable run."),
20
22
  },
21
- }, async ({ repoRoot, manifestPath, cycles = 1, resume = false }) => {
22
- const service = new RunCycleService();
23
+ }, async ({ repoRoot, manifestPath, cycles, untilTarget = false, untilNoImprove, fresh = false }) => {
24
+ const service = new RunLoopService();
23
25
  const resolvedRepoRoot = resolve(repoRoot ?? defaultRepoRoot);
24
- const results = [];
25
- for (let index = 0; index < cycles; index += 1) {
26
- const result = await service.run({
27
- repoRoot: resolvedRepoRoot,
28
- ...(manifestPath ? { manifestPath } : {}),
29
- resume,
30
- });
31
- results.push(result);
32
- if (result.status === "failed" || result.status === "resume_required") {
33
- break;
34
- }
35
- }
26
+ const result = await service.run({
27
+ repoRoot: resolvedRepoRoot,
28
+ ...(manifestPath ? { manifestPath } : {}),
29
+ ...(cycles === undefined ? {} : { cycles }),
30
+ ...(untilTarget ? { untilTarget } : {}),
31
+ ...(untilNoImprove === undefined ? {} : { untilNoImprove }),
32
+ fresh,
33
+ });
36
34
  return {
37
35
  content: [
38
36
  {
39
37
  type: "text",
40
- text: JSON.stringify({
41
- ok: results.every((result) => result.status !== "failed" && result.status !== "resume_required"),
42
- cycles,
43
- results,
44
- }, null, 2),
38
+ text: JSON.stringify(result, null, 2),
45
39
  },
46
40
  ],
47
41
  };
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "ralph-research",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Local-first runtime for recursive research improvement.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "rrx": "./dist/cli/main.js"
7
+ "rrx": "dist/cli/main.js"
8
8
  },
9
9
  "files": [
10
10
  "dist",
@@ -59,5 +59,12 @@ ratchet:
59
59
  metric: quality
60
60
  epsilon: 0
61
61
 
62
+ # Optional progressive-stop contract:
63
+ # stopping:
64
+ # target:
65
+ # metric: quality
66
+ # op: ">="
67
+ # value: 0.8
68
+
62
69
  storage:
63
70
  root: .ralph