Add a Rust-native fresh-agent Ralph loop #73

Closed
opened 2026-08-29 17:40:53 +00:00 by hugo · 1 comment
Owner

Goal

Add an explicit Rust-native Ralph tool that iterates toward one immutable coding objective with a fresh local-model context each round. The shared working tree is durable memory; only one bounded structured handoff crosses rounds.

Depends on #72 for executable tool schemas, validation, and reliable structured report capture.

Plan

  • Add the smallest reusable Rust entry point needed to run one fresh child generation with the selected model/runtime, current workspace, and applicable agent instructions, but no parent conversation, prior child messages, or inherited KV-cache history. Reuse the existing inference and tool stack rather than introducing a workflow framework.
  • Register a foreground ralph tool with required objective and optional max_rounds. Use an initial default of 8 rounds and a hard ceiling of 64; keep provider/model routing owned by the current session.
  • For every round, build a fixed prompt containing only the immutable objective, round number/cap, workspace-as-source-of-truth rules, and the previous validated report. Require the worker to inspect existing work, perform concrete in-scope work, and verify changes.
  • Capture exactly one report with status (continue, complete, or blocked), summary, evidence, next_steps, and blocker. Bound the serialized handoff to 16 KiB and reject malformed or oversized reports.
  • Enforce semantics: continue requires next steps and no blocker; complete requires concrete evidence and no next steps/blocker; blocked requires a concrete blocker. Prevent child agents from invoking ralph recursively.
  • Stop immediately on worker-reported completion or blocker, at the round cap, on cancellation, or when a child fails. Preserve the last valid handoff in failure results and label completion/blockers as worker reports rather than independent certification.
  • Reuse existing tool-card lifecycle reporting to show the active round and terminal outcome; do not add a separate workflow UI.
  • Add deterministic tests with a scripted/fake generation backend plus focused local-model evals comparing one ordinary session with bounded Ralph runs on repository tasks. Measure completion, false completion, repeated discovery, tokens, and wall time before changing defaults.

Boundaries

  • Rust only; no JavaScript runtime, model-authored workflow scripts, external agent process, or generic workflow engine.
  • Foreground sequential rounds only. No fan-out, parallel agents, background/resume scheduler, provider switching, or recursive Ralph calls.
  • Independent evaluator/verifier agents are out of scope; the result must remain explicitly worker-reported.

Acceptance criteria

  • Each round uses a distinct fresh child context with no parent/prior-child conversation leakage while sharing the same workspace and applicable repository instructions.
  • The only cross-round conversational state is the validated bounded report; workspace changes remain visible to later rounds.
  • Report schema and status semantics are enforced before a handoff or terminal result is accepted.
  • Round limits, cancellation, malformed reports, oversized handoffs, and child failures terminate cleanly without orphaned work.
  • The parent receives one bounded terminal result containing round count, status, evidence, and the final/last valid report.
  • DeepSeek V4 Flash and GLM paths have regression coverage for report capture and fresh-context isolation.
  • cargo fmt --all -- --check, Clippy with -D warnings, make bundle, and cargo test --all-features pass.
## Goal Add an explicit Rust-native Ralph tool that iterates toward one immutable coding objective with a fresh local-model context each round. The shared working tree is durable memory; only one bounded structured handoff crosses rounds. Depends on #72 for executable tool schemas, validation, and reliable structured report capture. ## Plan - Add the smallest reusable Rust entry point needed to run one fresh child generation with the selected model/runtime, current workspace, and applicable agent instructions, but no parent conversation, prior child messages, or inherited KV-cache history. Reuse the existing inference and tool stack rather than introducing a workflow framework. - Register a foreground `ralph` tool with required `objective` and optional `max_rounds`. Use an initial default of 8 rounds and a hard ceiling of 64; keep provider/model routing owned by the current session. - For every round, build a fixed prompt containing only the immutable objective, round number/cap, workspace-as-source-of-truth rules, and the previous validated report. Require the worker to inspect existing work, perform concrete in-scope work, and verify changes. - Capture exactly one report with `status` (`continue`, `complete`, or `blocked`), `summary`, `evidence`, `next_steps`, and `blocker`. Bound the serialized handoff to 16 KiB and reject malformed or oversized reports. - Enforce semantics: `continue` requires next steps and no blocker; `complete` requires concrete evidence and no next steps/blocker; `blocked` requires a concrete blocker. Prevent child agents from invoking `ralph` recursively. - Stop immediately on worker-reported completion or blocker, at the round cap, on cancellation, or when a child fails. Preserve the last valid handoff in failure results and label completion/blockers as worker reports rather than independent certification. - Reuse existing tool-card lifecycle reporting to show the active round and terminal outcome; do not add a separate workflow UI. - Add deterministic tests with a scripted/fake generation backend plus focused local-model evals comparing one ordinary session with bounded Ralph runs on repository tasks. Measure completion, false completion, repeated discovery, tokens, and wall time before changing defaults. ## Boundaries - Rust only; no JavaScript runtime, model-authored workflow scripts, external agent process, or generic workflow engine. - Foreground sequential rounds only. No fan-out, parallel agents, background/resume scheduler, provider switching, or recursive Ralph calls. - Independent evaluator/verifier agents are out of scope; the result must remain explicitly worker-reported. ## Acceptance criteria - Each round uses a distinct fresh child context with no parent/prior-child conversation leakage while sharing the same workspace and applicable repository instructions. - The only cross-round conversational state is the validated bounded report; workspace changes remain visible to later rounds. - Report schema and status semantics are enforced before a handoff or terminal result is accepted. - Round limits, cancellation, malformed reports, oversized handoffs, and child failures terminate cleanly without orphaned work. - The parent receives one bounded terminal result containing round count, status, evidence, and the final/last valid report. - DeepSeek V4 Flash and GLM paths have regression coverage for report capture and fresh-context isolation. - `cargo fmt --all -- --check`, Clippy with `-D warnings`, `make bundle`, and `cargo test --all-features` pass.
hugo added the enhancementcritical labels 2026-08-29 17:40:53 +00:00
Author
Owner

Implemented in f2772f2. Added a foreground Rust-native ralph tool (objective required, max_rounds default 8, hard max 64) that reuses the selected session's model/runtime, workspace, AGENTS.md prompt, tool catalog, validation, permissions, and tool-card lifecycle. Each round gets a unique transient KV namespace and a freshly constructed child message list containing only the immutable objective, round/cap, and previous validated report. Paginated output and repeat state are isolated per round; child-started background jobs are stopped at every boundary; recursive ralph calls are denied. The child-only ralph_report contract enforces continue/complete/blocked semantics, exactly one standalone report, and a 16 KiB serialized cap. Completion/blockers are explicitly labeled worker-reported, while cancellation, malformed reports, round caps, and child failures stop cleanly with the last valid report preserved. Added deterministic scripted-backend tests for fresh prompts and every terminal path, DeepSeek DSML and GLM report capture, report validation/oversize rejection, unique context cleanup, and orphan-job prevention. Verification: cargo fmt --all -- --check; cargo clippy --all-targets --all-features -- -D warnings; make bundle; cargo test --all-features (181 passed, 14 hardware/browser fixtures ignored).

Implemented in f2772f2. Added a foreground Rust-native ralph tool (objective required, max_rounds default 8, hard max 64) that reuses the selected session's model/runtime, workspace, AGENTS.md prompt, tool catalog, validation, permissions, and tool-card lifecycle. Each round gets a unique transient KV namespace and a freshly constructed child message list containing only the immutable objective, round/cap, and previous validated report. Paginated output and repeat state are isolated per round; child-started background jobs are stopped at every boundary; recursive ralph calls are denied. The child-only ralph_report contract enforces continue/complete/blocked semantics, exactly one standalone report, and a 16 KiB serialized cap. Completion/blockers are explicitly labeled worker-reported, while cancellation, malformed reports, round caps, and child failures stop cleanly with the last valid report preserved. Added deterministic scripted-backend tests for fresh prompts and every terminal path, DeepSeek DSML and GLM report capture, report validation/oversize rejection, unique context cleanup, and orphan-job prevention. Verification: cargo fmt --all -- --check; cargo clippy --all-targets --all-features -- -D warnings; make bundle; cargo test --all-features (181 passed, 14 hardware/browser fixtures ignored).
hugo closed this issue 2026-08-29 19:05:31 +00:00
Sign in to join this conversation.