Data Engineering · Systems Rust

Richard Lavoura

Python/SQL data engineering · 8 yrs · CHANEL, Kering

Richard is an 8-year data and analytics engineer, currently at CHANEL and previously embedded at Kering supporting Saint Laurent, Balenciaga, and Bottega Veneta, with missions at Carrefour, Stellantis, and Française des Jeux behind him. His Rust project is ferrit, a lazygit-style terminal UI for git, published under ferrit-rs.

The interesting part sits underneath the TUI: a headless git domain the UI never leaks into, a hybrid backend that reads through libgit2 and shells out to git where the user's config must win, a single audited seam for every process ferrit spawns, and a replay harness that tests the whole app deterministically. The crate forbids unsafe and denies unwrap, expect, panic, and unchecked indexing.

8 yrs
Data and analytics engineering
CHANEL
Analytics Engineer, now shipping a Rust CLI in prod
Kering, Carrefour, Stellantis
Freelance missions for Saint Laurent, Balenciaga, Bottega Veneta and more
First
Open source Rust project
The challenge

A git client that behaves exactly like git

A git TUI sits between an engineer and their history. If it diffs differently from the CLI, ignores a user's config, or hangs on an SSH passphrase prompt it cannot display, it loses trust on day one.

It also spawns processes on the user's machine, so every command it runs has to be visible and auditable, with credentials never written to the screen or the log.

  • •Diffs and hunk staging identical to the git CLI
  • •SSH and HTTPS prompts answered inside a raw-mode terminal
  • •No unsafe, no unwrap, no panic anywhere in the crate
The outcome

ferrit: public, audited, replay-tested

Richard has ferrit public on GitHub: interactive rebase with reword, drop, squash, fixup, and edit, a git config editor that shows each value's scope and origin with shadowed entries, a remappable keymap that generates its own help screen, and a repository dashboard computed off the UI thread.

He's already shipping Rust in production too, a Rust CLI for Microsoft Fabric built at CHANEL to automate authentication, workspace discovery, and partition refreshes, alongside 8 years of production data engineering habits proven in Rust.

  • ✓Every git process built in one place and logged with secrets redacted
  • ✓Whole-app scripted replays against deterministic fixture repos
  • ✓A Rust CLI already running in production at CHANEL
[ Git backend ]

libgit2 for reads, the real git binary wherever user config matters

Status, log, and branch reads go through git2 with a vendored libgit2, inside a headless domain::git module that never imports ratatui. Diffs and writes take the other path: git diff and git show subprocesses with lazygit's flag set, so diff drivers, rename detection, and hooks behave exactly as on the command line.

Staging a single hunk becomes a text slice of the diff fed to git apply --cached, parsed by a small byte-range scanner rather than a full diff library. The tradeoff is explicit: libgit2 where it is fast and stable, the git binary where fidelity to the user's own setup matters more than saving a process spawn.

[ Process seam ]

One constructor for every git process, enforced by a test

exec::git(workdir) is the only place in the crate that builds a git Command, and a test scans the source tree to keep it that way. Every call lands in a command log: a bounded ring buffer, read versus write classification, captured output for writes, and secrets redacted before anything reaches the screen.

The same seam solves credentials. ferrit owns raw mode, so a git child has no TTY to prompt on. ferrit registers itself as SSH_ASKPASS and GIT_ASKPASS: the child re-invokes the binary, which reaches the running TUI over a per-process socket, raises a masked prompt for passwords and passphrases, and hands the answer back.

[ Testing ]

Deterministic replay instead of screenshot snapshots

An in-process headless runner drives scripted sessions against deterministic fixture repos: fixed author, commit dates a minute apart, and local git config pinning signing and pull behaviour. Async keys run until the app reports idle instead of sleeping for a guessed duration.

Snapshot testing with insta was rejected because rendered frames contain branch ages that change every day. Every script must assert something, a planned flow that loses its script fails the build, and the hidden test flags are refused in release builds unless FERRIT_TEST is set.

[ Remote ops ]

Creating a GitHub remote without ever holding a token

Remote creation delegates to gh, injected as a program path rather than read from the environment. The target is validated, arguments are built only from checked fields, and repos are private by default: public needs an explicit y, and Enter cancels.

The call runs on the network worker slot with a timeout and cancellation, through a child-process runner split out of the git command builder so both share one supervision path.

The journey

One clear path through the build

Drag to explore · Select a milestone to read the full story

Max Wells

Mentor perspective

Richard Lavoura brought a data engineer's distrust of anything unverified, and it shaped ferrit. When fidelity to the user's git setup mattered more than avoiding a process spawn, he moved diffs to the real git binary instead of approximating it. When snapshots proved unstable, he built a deterministic replay harness rather than loosening the tests. That is systems judgment, not syntax.

Max Wells

Rustify mentor

Want results like Richard's?

Max WellsAvailable for calls

Max Wells

Founder · Rustify

Book your Rust career diagnostic

30 minutes, 1:1 with Max. An honest read on where you are and whether Bootcamp or Mentorship fits, before you apply.

Only a few diagnostic slots left this week.

Applications are reviewed carefully.

← Back to case studies

More client journeys

See another path into Rust

Ready to Land a $80k+ Rust Job in the US or Europe?