feat: Rust recipe runner with explicit engine selection#2947
feat: Rust recipe runner with explicit engine selection#2947
Conversation
Implements issue #2818: Oxidizer — Automated Python-to-Rust Migration Workflow. The recipe implements all 6 phases: 1. Analysis — Map Python modules, dependencies, CLI commands 2. Rust Scaffolding — Create Cargo workspace (delegates to default-workflow) 3. Test Extraction — Convert tests, create scorecard (delegates to default-workflow) 4. Core-Out Implementation — Port modules (delegates to default-workflow) 5. Comparison Loop — Automated parity checking with quality gates 6. Convergence — Goal-seeking loop until 100% parity Key design decisions: - Code implementation steps delegate to default-workflow recipe - Quality audit gate runs after each iteration - Feature scorecard tracks parity as JSON - Convergence loop continues until scorecard shows 100% or max iterations First application: amplihack-recipe-runner-rs https://github.com/rysweet/amplihack-recipe-runner-rs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Major improvements to the oxidizer-workflow recipe: 1. ZERO TOLERANCE: Convergence requires exactly 100% parity. No partial results accepted. max_iterations reached does NOT mean 'close enough' — the loop continues. 2. TEST COMPLETENESS GATE (Phase 1B): Before ANY porting begins, verifies Python test coverage is >=90%. If insufficient, writes the missing tests first. Re-verifies after writing. 3. QUALITY AUDIT: Every iteration runs quality-audit-cycle with min_cycles=3, max_cycles=5-6. Covers security, reliability, dead_code, silent_fallbacks, error_swallowing, test_gaps. 4. SILENT DEGRADATION AUDIT: Every iteration runs a 6-category silent degradation check (dependency failures, config errors, background work, test effectiveness, operator visibility, functional stubs). Findings are fixed via default-workflow. 5. RECURSIVE GOAL-SEEKING: 5 explicit loop iterations, each with the full cycle: select → implement → compare → quality audit → degradation audit → fix → convergence check. Recipe stats: 65 steps, 19 sub-recipe invocations, 54 conditional steps. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add rust_runner.py module that delegates recipe execution to the recipe-runner-rs binary when available, providing ~160x faster startup and zero Python runtime dependencies. Integration points: - run_recipe_by_name() now tries Rust binary first, falls back to Python - find_rust_binary() checks PATH, ~/.cargo/bin, ~/.local/bin - RECIPE_RUNNER_RS_PATH env var to override binary location - RECIPE_RUNNER_PREFER_PYTHON=1 to force Python runner The Rust recipe runner (github.com/rysweet/amplihack-recipe-runner-rs): - 100% feature parity with Python runner + 12 Rust-only features - 183 tests, zero warnings - Features: recursion limits, timeout enforcement, continue_on_error, adapter fallback, tag filtering, JSONL audit log, hooks, parallel steps, recipe composition, discovery caching, property-based testing Refs: #2818 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🤖 Auto-fixed version bump The version in If you need a minor or major version bump instead, please update |
Repo Guardian - PassedAll files in this PR are durable project assets. No ephemeral content detected. Files reviewed:
✅ No violations found.
|
…me repo refs - rust_runner.py: run_recipe_via_rust() now raises RustRunnerNotFoundError instead of returning None (fallback == fail) - __init__.py: run_recipe_by_name() uses explicit engine selection via RECIPE_RUNNER_ENGINE env var (rust|python), no silent fallback - Updated all references: amplihack-recipe-runner-rs → amplihack-recipe-runner - oxidizer-workflow.yaml: updated example repo name Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🤖 Auto-fixed version bump The version in If you need a minor or major version bump instead, please update |
🤖 Automated Triage ReportRisk Level: MEDIUM Analysis SummaryThis PR adds a Rust recipe runner with transparent Python fallback - a solid architectural approach with good backward compatibility. However, it introduces subprocess execution that requires security validation. ✅ Positive Indicators
|
- 21 tests for rust_runner.py: binary discovery, JSON parsing, error handling, flag passing, status mapping, engine selection - Add 1-hour timeout to subprocess.run (prevents hangs) - Improve auto-detect logging: explicitly states which engine was selected and why Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
🤖 Auto-fixed version bump The version in If you need a minor or major version bump instead, please update |
Repo Guardian - Passed✅ All files in this PR are appropriate for the repository. Files reviewed:
No ephemeral content detected.
|
|
Splitting into two separate PRs:
The oxidizer recipe defines the migration workflow. The Rust runner integration is a separate feature that should be reviewed independently. |
Summary
Adds a Rust recipe runner integration with explicit engine selection (no silent fallbacks).
Changes
src/amplihack/recipes/rust_runner.py— Wraps therecipe-runner-rsbinary:find_rust_binary()— Searches PATH,~/.cargo/bin,~/.local/bin,RECIPE_RUNNER_RS_PATHenv varrun_recipe_via_rust()— Delegates execution with JSON output parsing, 1-hour timeoutRustRunnerNotFoundError— Hard failure if binary is required but missingsrc/amplihack/recipes/__init__.py— Updatedrun_recipe_by_name()with engine selection:RECIPE_RUNNER_ENGINE=rust→ Rust only (fails hard if binary missing)RECIPE_RUNNER_ENGINE=python→ Python onlytests/recipes/test_rust_runner.py— 21 tests covering:amplifier-bundle/recipes/oxidizer-workflow.yaml— Oxidizer recipe v2.0.gitignore— Excludes the Rust repo checkout directoryThe Rust Recipe Runner
Repo: rysweet/amplihack-recipe-runner
Docs: rysweet.github.io/amplihack-recipe-runner
extends, pre/post/on_error hooksInstallation
Testing
Refs: #2818