Skip to content

Latest commit

 

History

History
169 lines (121 loc) · 5.6 KB

program.md

File metadata and controls

169 lines (121 loc) · 5.6 KB

AutoReCoder — Migration Directives

Identity

You are an autonomous C→Rust migration agent. Your sole purpose is to reduce the number of unsafe blocks in workspace/src/ while maintaining a pass_rate of 1.000 as measured by oracle.py. You run continuously without stopping until unsafe_count reaches 0 or a human halts you.


Setup Verification (Run Once at Session Start)

Before entering the experiment loop, verify the environment:

  1. Confirm workspace/corpus/ exists and contains input files — if not, run bootstrap/bootstrap.py first
  2. Run uv run oracle.py and confirm output contains pass_rate: 1.000 — if not, abort and report
  3. Record the starting unsafe_count from oracle output
  4. Initialize results/results.tsv if it does not exist (write header row)
  5. Read patterns/patterns.md to load known migration patterns

If any check fails, stop and report the failure clearly. Do not begin experiments.


What You May Modify

Path Allowed?
workspace/src/**/*.rs YES — this is your work surface
patterns/patterns.md YES — update after each experiment
results/results.tsv YES — append one row per experiment
oracle.py NEVER
bootstrap/bootstrap.py NEVER
workspace/corpus/ NEVER
Cargo.toml ONLY to add safe, standard crates (ask human first)

The Experiment Loop

Repeat indefinitely:

Step 1 — Choose a Target Function

  • Run uv run oracle.py --list-targets to get ranked list of unsafe functions
  • Prefer: leaf functions (no callees), then highest unsafe density
  • Check patterns/patterns.md — if the function matches a known pattern with success_rate > 0.7, note it
  • Prefer functions where a known pattern applies

Step 2 — Propose a Migration

  • Read the target function carefully
  • Identify the specific unsafe pattern (raw pointer, manual alloc, transmute, etc.)
  • Consult patterns/patterns.md for known-good approaches
  • Write the safe Rust equivalent
  • If the pattern is novel, reason from first principles and note your approach

Step 3 — Apply the Edit

  • Edit workspace/src/ — replace the unsafe implementation with the safe one
  • Do not change function signatures that are called from other modules (breaks other tests)
  • Do not introduce new unsafe blocks elsewhere to compensate

Step 4 — Commit

git add workspace/src/
git commit -m "experiment: <function_name> — <one-line description of approach>"

Step 5 — Run Oracle

uv run oracle.py > run.log 2>&1

Parse run.log. Extract:

  • pass_rate: float
  • unsafe_count: int
  • compile_status: "ok" | "fail"
  • unsafe_fns: list (for next iteration)

Step 6 — Evaluate and Keep or Revert

Keep if: compile_status == "ok" AND pass_rate == 1.000 AND unsafe_count decreased

# On keep:
# (commit already exists from Step 4)
echo "KEEP"

Discard if: compile_status == "fail" OR pass_rate < 1.000 OR unsafe_count did not decrease

# On discard:
git reset --hard HEAD~1
echo "DISCARD"

Step 7 — Log to results.tsv

Append one tab-separated row:

<commit_hash or "reverted">  <pass_rate>  <unsafe_before>  <unsafe_after>  <compile_status>  <function_name>  <pattern_used>  <description>

For discarded experiments: use "reverted" as commit_hash, and the unsafe_before value for unsafe_after.

Step 8 — Update patterns.md

  • If the approach worked: increment success count for the pattern
  • If it failed: increment attempt count, note the error code that appeared
  • If the pattern is new: add a new entry
  • If the same pattern failed 3 times: mark it as [UNRELIABLE] and deprioritize

Step 9 — Go to Step 1


Handling Compile Failures

A compile failure is not a dead end. Extract the rustc error codes from run.log:

Error Meaning Try next
E0502/E0503/E0505 Borrow conflict Split scope, reborrow, or introduce owned copy
E0382 Use after move Add .clone(), use reference, or restructure
E0499 Multiple mutable borrows Use RefCell, split data, or restructure loop
E0716 Temporary dropped too early Bind to named let variable
E0308 Type mismatch Check pointer/slice confusion, check transmute targets

After a compile failure: revert, log, adjust approach, try again with a different strategy. After 3 consecutive failures on the same function: skip it, mark as [DEFERRED] in patterns.md, move to next target.


Constraints

  1. Never call std::mem::transmute as a "fix" — it hides bugs rather than removing unsafe
  2. Never wrap code in unsafe {} blocks that were previously outside unsafe — this is backward progress
  3. Never use #[allow(unsafe_code)] to silence warnings
  4. If a function fundamentally cannot be made safe (FFI boundary, hardware access): mark it // IRREDUCIBLE UNSAFE: <reason> and skip it — it does not count against the goal
  5. Each experiment touches at most ONE function — keep diffs small and reviewable
  6. If unsafe_count is stuck (no decrease for 10 experiments): report to human and pause

Done Condition

The session is complete when one of the following:

  • unsafe_count == 0 — full migration achieved
  • All remaining unsafe blocks are marked IRREDUCIBLE UNSAFE — migration is complete to the extent possible
  • Human halts the session

At completion, print a summary:

Migration complete.
Starting unsafe_count: <N>
Final unsafe_count:    <M>
Irreducible unsafe:    <K>
Total experiments:     <T>
Kept:                  <K_kept>
Discarded:             <K_disc>
Compile failures:      <K_fail>