Rhiza

The Living Template System

Keeping every Python repo in sync — automatically

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Agenda

  1. The Repo Zoo Problem — what goes wrong at scale
  2. Why existing tools fall short — the Day 0 / Day 365 gap
  3. How Rhiza works — core concepts and the sync loop
  4. Getting started — four commands
  5. Living with Rhiza — sync PRs, customisation
  6. The ecosystem — tooling and real-world users
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Part 1

The Repo Zoo Problem

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

How every team starts

A new project? Run the generator.

cookiecutter gh:my-org/python-template

✓ CI workflow — wired up
✓ Makefile — ready
✓ Linting config — configured
✓ Test harness — set

Day 0 is great. Everything is consistent.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Then time passes.

The backtesting repo got a pre-commit hook the risk model never received.

The data pipeline still pins Python 3.9 — EOL since October 2024.

Three repos use Black. Two use Ruff. One uses both.

The reporting dashboard references a GitHub Actions runner deprecated eight months ago.

Nobody did this on purpose. It just happens.

Each repo drifted into a different breed — incompatible with the others, living in its own enclosure, expensive to maintain on its own terms.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The real cost

Every change made to one repo is a change not made to the others.

CVE in a GitHub Actions runner
You need to update 17 repos. You do 12, get distracted. Five months later, five are still vulnerable.

Python 3.9 reaches end-of-life
You update the active repos. The legacy repos drift on, unpatched.

Team decides to standardise on Ruff
Active repos updated. Legacy repos still run Black. "Our standard" is now a fiction.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Part 2

Why Existing Tools Fall Short

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The tools we reach for

Tool What it does The gap
Cookiecutter Generates files once Template and project disconnect immediately — no update path
Copier Records the template, supports copier update Manual, per-repo command — no scheduling, no PRs, no org-wide trigger
GitHub template repos One-click clone at a point in time That's all. No sync, no version pinning, no update mechanism
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The Day 0 / Day 365 gap

All of these tools were designed to solve the Day 0 problem:

Getting a new project off the ground with sensible defaults.

None were designed for the Day 365 problem:

Keeping twenty existing projects aligned as shared infrastructure evolves.

Template systems treat configuration as something you set up once.
But configuration is not a one-time decision — it is ongoing infrastructure.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The insight

Born from experience at a large sovereign wealth fund: dozens of Python repos, multiple teams, no mechanism to stay aligned. The problem was not carelessness — it was structural. One-shot scaffolding produces drift by design.

Treat the update as a pull request, not a push.

Instead of forcing changes into downstream repos, Rhiza opens a PR in each one:

  • Clean diff of what changed in the template
  • Owner reviews, adapts if necessary, merges
  • Opt-in per repo — systematic across the organisation

The sync is not a bulldozer. It is a proposal.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Part 3

How Rhiza Works

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Three actors

template repo
Jebel-Quant/rhiza  ·  or your org's fork
↓  sync PRs
your project
.rhiza/template.yml
↑  sync
uvx rhiza
the syncer — runs locally or in CI
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The config file: .rhiza/template.yml

repository: Jebel-Quant/rhiza   # Which template repo to sync from
ref: v0.8.0                      # Which version (pinned tag — recommended)

templates:                        # Named bundles of files to include
  - core
  - github
  - tests
  - renovate

exclude: |                        # Files you own locally — never overwritten
  ruff.toml
  Makefile.local

One file. That's all Rhiza needs.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Bundles — named groups of files

Bundle What it includes
core Makefile, ruff.toml, pre-commit config, editor config
github All GitHub Actions CI/CD workflows
tests pytest config, coverage, security scanning
docker Dockerfile and container CI workflow
marimo Interactive notebook support
presentation Slide generation from Markdown (Marp)
renovate Automated dependency update config

core is always required. All others are optional.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The sync loop

fetch
diff
review
commit
  1. Fetch — reads template.yml, pulls matching files from the template repo at ref
  2. Diff — compares what was fetched against what's currently in your project
  3. Review — if anything changed, opens a pull request with the diff
  4. Commit — you review the PR and merge it (or close it if not relevant)

Runs automatically on a weekly schedule via GitHub Actions.
On-demand: make sync or uvx rhiza sync.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Renovate — closing the loop

Without Renovate, the ref: pin is frozen. Projects drift behind the template silently.

template repo publishes v0.9.0
Renovate opens PR: ref: v0.8.0 → v0.9.0  (one line diff)
you merge
sync workflow applies updated CI files, linting config, etc.

Two separate PRs: should we upgrade? then here's what changed.
Opt-in per repo. Systematic across the organisation.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Part 4

Getting Started

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Four commands

# 1. Install uv (skip if already installed)
curl -LsSf https://astral.sh/uv/install.sh | sh

# 2. Initialise — writes .rhiza/template.yml interactively
uvx rhiza init

# 3. Sync — fetches template files and writes them into the project
uvx rhiza sync

# 4. Install dev environment
make install

That's it. Your project is now Rhiza-managed.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

What you get on day one

After syncing with core + github + tests + renovate:

.github/workflows/rhiza_ci.yml          ← CI: test on push and PRs
.github/workflows/rhiza_pre-commit.yml  ← Pre-commit checks in CI
.github/workflows/rhiza_sync.yml        ← Weekly template sync
.pre-commit-config.yaml                 ← Local commit hooks
ruff.toml                               ← Linting config
Makefile                                ← make test · make lint · make release
.python-version                         ← Pinned Python version
.editorconfig                           ← Editor consistency

None of this required manual configuration.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Part 5

Living with Rhiza

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Reading a sync PR

A sync PR is a standard git diff of template files that changed.

Green (added) — new template content your project doesn't have yet.
Usually safe to accept.

Red (removed) — content removed from the template.
Check whether anything you depend on is being removed.

Changed — read carefully. Could be a workflow version bump, a lint rule adjustment, or a security fix.

The PR description usually explains what changed at a high level.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Accept, modify, or reject?

Accept as-is — CI workflow updates, runner version bumps, linting adjustments that apply cleanly and tests pass.

Modify before merging — the change applies but needs a small tweak for your project. Or: add a file to exclude: in template.yml before merging.

Close without merging — the change isn't relevant (e.g. Docker support in a project that won't use containers).

Closing is fine. The next sync will re-open the PR
if the template still differs from your project.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Customising safely

Need Mechanism
Custom make targets Edit custom-task.mk (never overwritten)
Project-specific env vars Edit custom-env.mk (never overwritten)
Permanently own a specific file Add to exclude: in template.yml
Custom standards for your whole org Fork the template repo

Never edit template-managed files directly unless you also add them to exclude:.
Your change will be overwritten on the next sync.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Part 6

The Ecosystem

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

The Rhiza ecosystem

Tool What it does
rhiza-cli uvx rhiza init / sync / validate — the tool you run
rhiza-hooks Pre-commit hooks: validate config, check version consistency
rhiza-tools bump, release, version-matrix, coverage-badge
rhiza-go The same living-template pattern for Go projects
repo-monitor Desktop dashboard: workflow status, open PRs, Renovate state
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Who's using it

The Rhiza tools themselves — rhiza-cli, rhiza-hooks, and rhiza-tools all sync from rhiza. The system eats its own cooking.

External projects:

Project Organisation Bundles
simulator Stanford CVXGRP core + github + tests
jsharpe tschm core + github + marimo
loman Janus Henderson core + github + tests + renovate
chebpy chebpy core + github
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Key takeaways

  1. The repo zoo is structural — drift is the default outcome of one-shot scaffolding, not a failure of discipline.

  2. Existing template tools solve Day 0. Rhiza solves Day 365.

  3. The core insight: treat updates as pull requests, not pushes. Systematic coverage, opt-in per repo.

  4. Setup is four commands. Ongoing maintenance is reviewing a weekly PR.

  5. You stay in control. exclude:, custom extension files, and org forks give full flexibility without fighting the sync.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown

Get started

uvx rhiza init

ῥίζα (ree-ZAH) — root

https://jebel-quant.github.io/rhiza-education/

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v0.8.5 / rhiza-cli unknown