SafeLibs

SafeLibs builds memory-safe (Rust) reimplementations of critical load-bearing C/C++ libraries used throughout open source infrastructure, while attempting to preserve drop-in compatibility at compile-time and runtime.

Mission

  • Reimplement widely-used C/C++ libraries in Rust for memory safety.
  • Preserve C ABI and behavioral compatibility so existing consumers can relink without source changes.
  • Keep ports practical for production by retaining performance characteristics.

Priorities

  1. Drop-in compile-time and runtime compatibility.
  2. Performance.
  3. Memory safety.

Maintainability

Non-goal

Long-term maintainability of each individual translated codebase is not a primary goal.

Maintainability

The working model is retranslating from upstream as original projects evolve (eventually, maybe nightly!), then re-validating compatibility and performance. In fact, we will NOT accept code PRs to the ported libraries themselves: we don't know the codebase well enough to reason about malicious patches, etc. We'll happily accept issues against the repo with an example of the failing workflow, then sic our agents on them, though!

Pipeline

This repo uses a four-stage pipeline driven by Juvenal (https://github.com/zardus/juvenal), a workflow manager named after the Roman poet — riffing on "who watches the watchmen?" Each stage uses one or more Juvenal workflows to achieve and verify its goals despite agentic laziness, and each successful stage produces a git tag in the respective repo.

Juvenal leans on a behavioral quirk of coding agents: they will happily cut corners on their own work, but have no incentive to cover for another agent's shortcuts. After every implementation step, several fresh-context validation agents check the result against different criteria; anything missing bounces back to the implementer, dozens of times if necessary. The Port stage in particular doesn't share a workflow across libraries — a planning agent drafts and iteratively refines a library-specific workflow before any porting starts, because no single template fits every C library.

The full pipeline definitions live in the pipeline repo.

01

Recon

pull the original source (via Ubuntu's source packages) and existing CVEs, so the port has historical context for known non-memory issues.

02

Setup

prepare the source for porting, rewriting tests to use public library APIs (so they survive a clean reimplementation) and adding new ones, both directly against the library and through dependent applications.

03

Port

do the rust port. A planning agent first builds a library-specific workflow, then implementation and validation agents execute and check it step by step.

04

Test

exercise the port against additional client applications and the validator suite.

Project Structure

Port Status

As of April 21, 2026, the SafeLibs org has 16 library port-* repositories that currently pass the validator proof at port-04-test, plus the shared port-template repository. They are all private right now, so this public site is intentionally not pretending to have a live public scoreboard yet. When the verification artifacts are ready to expose, this section should show actual compatibility results instead of vibes.

Port Effort Stats

Per-library token spend, agent time, and unsafe-block counts across the 16 validating port-* repos. The validator at https://safelibs.github.io/validator/site-data.json drives this list, and rows are filtered at site-build time so the table follows live validator results. In total: 4,243 sessions, 9.45B tokens, 597.0 agent-hours from March 27 to April 11, 2026 UTC, with a stage-token split of 0.98B recon, 1.54B setup, 4.27B port, 2.67B test.

Stage columns follow each repo's 01-recon/02-setup/03-port/04-test tags; sessions past the last completed tag count toward the next in-progress stage, which is why ports still in earlier stages show partial column coverage. Agent time is the sum of per-session wall time, so parallel sessions add up as parallel agent-hours.

The unsafe columns split each port's unsafe { ... } blocks two ways: ABI unsafe is forced by the C surface (functions taking *const T/*mut T, extern "C" functions, or unsafe fn exposed across the FFI boundary), and Other unsafe is everything else — transmutes, raw allocator handoff, intrinsics, static mut, etc. Across all 16 validating ports: 9,944 blocks total, 8,490 (85.4%) ABI and 1,454 (14.6%) other. The ABI share is largely a tax for staying drop-in compatible with existing C consumers; relaxing that constraint (e.g. for a Rust-only consumer story or a non-ABI-stable distro target) would let a future pipeline drop a large fraction of those blocks.

LibraryCompleted stageSessionsTotal tokensRecon tokensSetup tokensPort tokensTest tokensAgent timeCalendar spanTotal unsafeABI unsafeOther unsafe
cjson04-test121292.5M3.8M77.1M93.7M117.8M18.1h17.1h550
giflib04-test202281.5M2.5M56.2M121.4M101.4M22.7h22.2h52251012
libarchive04-test294731.3M8.3M88.9M376.8M257.2M37.3h35.0h574348226
libbz204-test157237.0M2.3M31.5M139.4M63.7M18.1h16.8h83380
libcsv04-test96121.4M4.4M11.7M40.1M65.1M11.0h10.1h1168135
libexif04-test840986.7M3.1M117.4M149.9M716.3M73.8h92.7h1,2051,16540
libjansson04-test219330.8M2.9M38.1M231.7M58.1M28.6h69.6h80579015
libjpeg-turbo04-test255804.2M2.5M91.0M406.2M304.6M72.3h57.7h79178
libjson04-test143328.7M2.6M50.1M109.0M167.0M23.3h21.9h1049311
liblzma04-test120470.7M2.7M33.5M357.6M76.9M21.2h19.1h29624272
libsodium04-test136276.7M6.8M22.0M190.4M57.5M18.9h18.2h53249735
libtiff04-test204577.5M6.4M23.6M478.2M69.3M30.9h27.3h3333276
libuv04-test5321,489.1M918.0M84.8M292.1M194.3M80.6h101.2h3,4103,024386
libwebp04-test154390.8M2.9M26.9M215.8M145.1M20.9h20.4h19413361
libxml04-test4631,757.6M6.1M749.3M884.8M117.4M85.2h75.5h1,5601,425135
libyaml04-test307376.3M1.9M34.0M187.2M153.3M34.1h37.9h1266462

Other Efforts

  • DARPA's TRACTOR program (Translating All C To Rust) is the broader DoD-funded push behind agentic C-to-Rust translation, and a conceptual ancestor of work like this.
  • The "ralph loop" pattern at https://github.com/snarktank/ralph is a popular minimal harness for keeping agents on-task across long jobs; SafeLibs uses a structured planning + validation pipeline instead, but starts from the same observation that agents quit early on big tasks.

Compatibility Contract

A completed SafeLibs port should provide:

  • Binary-compatible exported symbols.
  • C headers compatible with existing consumer builds.
  • Equivalent runtime semantics for valid inputs.
  • Upstream test-suite parity plus consumer integration validation.

Verification Philosophy

SafeLibs verification is clean-room by design:

  • Run baseline tests against the original Ubuntu C library package.
  • Purge original runtime/dev packages from the test environment.
  • Install SafeLibs-generated .deb replacements.
  • Re-run the exact same tests and consumer checks.

If a port still forwards to the original C implementation, the replacement stage fails after purge.

FAQ

Why Rust instead of some other memory-safe language?
 ▐▛███▜▌   Claude Code
▝▜█████▛▘  Optimus 9000.1 · Claude ALL_YOUR_MONEY_PLAN
  ▘▘ ▝▝    /home/YOU
                                                                                
────────────────────────────────────────────────────────────────────────────────
❯ Change this repository from Rust to YOUR_LANGUAGE_HERE
────────────────────────────────────────────────────────────────────────────────
How many tokens does this take?

Any answer to this question will be meaningless, because it will be obsolete in a few weeks and I don't want to update this README that often.

Do you guarantee I won't get hacked?

rofl

In all seriousness, no one but the AI has ever looked at this code, and that goes for both the actual library reimplementations and the pipeline itself. Even if the libraries are perfect (and I'm sure they're not!), the best they'll do is protect against some memory safety issues in the original library. The actual programs using these libraries can still be vulnerable, or other libraries can be vulnerable, or the unsafe parts of these libraries can still be vulnerable, or there could be new and exotic non-memory errors in these libraries, or these libraries might set your computer on fire and turn your AI agent against you. I don't use these things, and you'd be crazy to, but they're there if you want to try them out!

Are these libraries correct?

These libraries pass adapted test cases from the original projects, and work in a drop-in manner with at least one client application. Beyond that, who knows!

But should I use these libraries?

If you still have a sandbox on in your AI agent, you should probably not use these libraries. If your agent's sandbox is off, you have already made the leap!

Why does this pipeline use codex and not claude?

Unfortunately, despite Claude's dominance, Codex gives FAR more tokens in their top plan, so that's what we're using here. If you harness it brutally enough, like it's harnessed here, it sometimes works!

How are the agents harnessed?

This repo uses a four-stage pipeline driven by Juvenal (https://github.com/zardus/juvenal), a workflow manager named after the Roman poet — riffing on "who watches the watchmen?" Each stage uses one or more Juvenal workflows to achieve and verify its goals despite agentic laziness, and each successful stage produces a git tag in the respective repo.

Juvenal leans on a behavioral quirk of coding agents: they will happily cut corners on their own work, but have no incentive to cover for another agent's shortcuts. After every implementation step, several fresh-context validation agents check the result against different criteria; anything missing bounces back to the implementer, dozens of times if necessary. The Port stage in particular doesn't share a workflow across libraries — a planning agent drafts and iteratively refines a library-specific workflow before any porting starts, because no single template fits every C library.

  1. Recon - pull the original source (via Ubuntu's source packages) and existing CVEs, so the port has historical context for known non-memory issues.
  2. Setup - prepare the source for porting, rewriting tests to use public library APIs (so they survive a clean reimplementation) and adding new ones, both directly against the library and through dependent applications.
  3. Port - do the rust port. A planning agent first builds a library-specific workflow, then implementation and validation agents execute and check it step by step.
  4. Test - exercise the port against additional client applications and the validator suite.

The full pipeline definitions live in the pipeline repo.

What about upgrading to new library versions?

Each port is a regenerable artifact — the workflow can be rerun from scratch against a new upstream release. There's also a dedicated upgrade stage in the pipeline that's intended to be cheaper than full retranslation, though it hasn't been battle-tested yet.

Will these work outside of Ubuntu?

The current focus is Ubuntu drop-in replacements via apt, which forces strict ABI compatibility and shapes a sizable chunk of the unsafe-block count. Distributions with stricter, content-addressed semantics (like Nix) would be a better fit for agent-generated replacements; if you're interested in extending coverage there, get in touch.

How do I report a port bug?

We can't accept code patches against the ported libraries — we don't audit the generated Rust closely enough to reason about adversarial PRs. We do accept reproducer testcases against the validator repo — the Test stage picks those up and re-runs the affected port until it passes.