Skip to content

feat: Rust recipe runner with explicit engine selection#2947

Closed
rysweet wants to merge 8 commits intomainfrom
feature/rust-recipe-runner
Closed

feat: Rust recipe runner with explicit engine selection#2947
rysweet wants to merge 8 commits intomainfrom
feature/rust-recipe-runner

Conversation

@rysweet
Copy link
Owner

@rysweet rysweet commented Mar 8, 2026

Summary

Adds a Rust recipe runner integration with explicit engine selection (no silent fallbacks).

Changes

  1. src/amplihack/recipes/rust_runner.py — Wraps the recipe-runner-rs binary:

    • find_rust_binary() — Searches PATH, ~/.cargo/bin, ~/.local/bin, RECIPE_RUNNER_RS_PATH env var
    • run_recipe_via_rust() — Delegates execution with JSON output parsing, 1-hour timeout
    • RustRunnerNotFoundError — Hard failure if binary is required but missing
  2. src/amplihack/recipes/__init__.py — Updated run_recipe_by_name() with engine selection:

    • RECIPE_RUNNER_ENGINE=rust → Rust only (fails hard if binary missing)
    • RECIPE_RUNNER_ENGINE=python → Python only
    • Not set → Auto-detect: Rust if binary found, Python otherwise. Logs which engine was selected.
    • Zero fallback patterns — chosen engine must succeed or fail
  3. tests/recipes/test_rust_runner.py — 21 tests covering:

    • Binary discovery (env var priority, PATH lookup, not found)
    • Recipe execution (flags, context, JSON parsing, status mapping)
    • Error handling (missing binary, bad output, timeout)
    • Engine selection (explicit rust/python, auto-detect, hard failure)
  4. amplifier-bundle/recipes/oxidizer-workflow.yaml — Oxidizer recipe v2.0

  5. .gitignore — Excludes the Rust repo checkout directory

The Rust Recipe Runner

Repo: rysweet/amplihack-recipe-runner
Docs: rysweet.github.io/amplihack-recipe-runner

  • 216 tests, zero warnings
  • Parallel step execution, tag filtering, JSONL audit logs
  • Recipe composition via extends, pre/post/on_error hooks
  • Safe condition language with recursive descent parser
  • Self-building specification recipe (30 steps)

Installation

cargo install --git https://github.com/rysweet/amplihack-recipe-runner

# Or set path explicitly
export RECIPE_RUNNER_RS_PATH=/path/to/recipe-runner-rs

Testing

# Run the new tests
uv run pytest tests/recipes/test_rust_runner.py -v

# Force specific engine
RECIPE_RUNNER_ENGINE=python uv run pytest ...
RECIPE_RUNNER_ENGINE=rust uv run pytest ...

Refs: #2818

Ubuntu and others added 4 commits March 7, 2026 23:08
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>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🤖 Auto-fixed version bump

The version in pyproject.toml has been automatically bumped to the next patch version.

If you need a minor or major version bump instead, please update pyproject.toml manually and push the change.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

Repo Guardian - Passed

All files in this PR are durable project assets. No ephemeral content detected.

Files reviewed:

  • .claude/context/PROJECT.md - Context documentation
  • .gitignore - Configuration file
  • amplifier-bundle/recipes/oxidizer-workflow.yaml - Workflow configuration
  • pyproject.toml - Project configuration
  • src/amplihack/recipes/__init__.py - Python module
  • src/amplihack/recipes/rust_runner.py - Python module

✅ No violations found.

AI generated by Repo Guardian

Ubuntu and others added 2 commits March 8, 2026 01:38
…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>
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🤖 Auto-fixed version bump

The version in pyproject.toml has been automatically bumped to the next patch version.

If you need a minor or major version bump instead, please update pyproject.toml manually and push the change.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🤖 Automated Triage Report

Risk Level: MEDIUM
Priority: HIGH
Recommendation: Needs Testing + Security Review

Analysis Summary

This 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

  • Zero breaking changes (transparent fallback to Python)
  • Opt-out mechanism available (RECIPE_RUNNER_PREFER_PYTHON=1)
  • Significant performance improvement (800ms → 5ms startup)
  • External Rust binary has 183 tests with 100% feature parity
  • Well-documented integration

⚠️ Key Concerns

  1. Security: Subprocess execution with path search including user directories (~/.cargo/bin)
  2. Testing: No visible test additions in changed files (needs verification)
  3. Error handling: JSON parsing at Python-Rust boundary needs review
  4. CI Status: Pending - no results yet (PR < 2 hours old)

📋 Required Before Merge

  1. ✅ Wait for CI results
  2. 🔍 Security review of path handling (prevent code injection via PATH manipulation)
  3. 🧪 Verify Python fallback works when Rust binary unavailable
  4. 🧪 Test RECIPE_RUNNER_PREFER_PYTHON=1 opt-out
  5. 🧪 Test error handling with malformed Rust output
  6. 📊 Validate JSON parsing at boundary

Labels Applied

  • triage:complete - Initial triage completed
  • triage:medium-risk - Subprocess security concerns
  • triage:needs-testing - Requires comprehensive testing
  • triage:security-review - Path handling needs validation

Generated by PR Triage Automation - 2026-03-08 02:31 UTC

AI generated by PR Triage Agent

- 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>
@rysweet rysweet changed the title feat: Rust recipe runner with transparent Python fallback feat: Rust recipe runner with explicit engine selection Mar 8, 2026
@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

🤖 Auto-fixed version bump

The version in pyproject.toml has been automatically bumped to the next patch version.

If you need a minor or major version bump instead, please update pyproject.toml manually and push the change.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 8, 2026

Repo Guardian - Passed

✅ All files in this PR are appropriate for the repository.

Files reviewed:

  • .claude/context/PROJECT.md — Project documentation template
  • .gitignore — Configuration file
  • amplifier-bundle/recipes/oxidizer-workflow.yaml — Durable recipe specification for automated workflows
  • pyproject.toml — Version metadata
  • src/amplihack/recipes/__init__.py — Production code
  • src/amplihack/recipes/rust_runner.py — New module for Rust integration
  • tests/recipes/test_rust_runner.py — Test coverage

No ephemeral content detected.

AI generated by Repo Guardian

@rysweet
Copy link
Owner Author

rysweet commented Mar 8, 2026

Splitting into two separate PRs:

  1. Oxidizer recipe only (this concern)
  2. Rust recipe runner integration (separate concern)

The oxidizer recipe defines the migration workflow. The Rust runner integration is a separate feature that should be reviewed independently.

@rysweet rysweet closed this Mar 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant