Rhiza

The Living Template System

Keeping every Python repo in sync — automatically

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

Part 1

The Repo Zoo Problem

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

Part 2

Why Existing Tools Fall Short

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

Part 3

How Rhiza Works

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Three actors

template repo
Jebel-Quant/rhiza  ·  or your org's fork
↓  sync PRs
your project
.rhiza/template.yml
↑  /rhiza:update
rhiza-claude
the interface — /rhiza:* commands you run in Claude Code
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

The config file: .rhiza/template.yml

repository: Jebel-Quant/rhiza   # Which template repo to sync from
ref: v1.7.1                      # Which version (pinned tag — recommended)
language: python                 # Which language layer (python / rust / go)

profiles:                         # Curated bundle preset (recommended)
  - github-project

exclude: |                        # Files you own locally — never overwritten
  SECURITY.md
  .github/CONFIG.md

One file. That's all Rhiza needs.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Bundles — named groups of files

Feature bundles (local tooling, no CI/CD):

Bundle What it includes
core Makefile shim (pins rhiza-task), editor config — language-neutral
python-core Python layer: virtualenv, ruff, bandit, deptry, pytest, hook config
book Docs site, notebooks, coverage badge
docker Dockerfile and container configuration
presentation Slide generation from Markdown (Marp)
renovate Automated dependency update config

core defines no install and no all — a language layer (python-core, rust-core, go-core) supplies them. Pick exactly one.

Since v1.4.0 bundles ship configuration only. The tasks live in a pinned CLI, rhiza-task.

Platform overlay bundles layer CI/CD on top: github-tests, github-book, gitlab-tests, etc.

Profiles (github-project, gitlab-project, local, rust-local, go-local) expand to a sensible bundle combination. Start here.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

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 (scoring is /rhiza:quality)
  4. Commit — you review the PR and merge it (or close it if not relevant)

Run it on demand with /rhiza:update in Claude Code — it bumps the ref, syncs the files, resolves conflicts, and opens the PR.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Renovate — closing the loop

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

template repo publishes v1.7.1
Renovate opens PR: ref: v1.7.0 → v1.7.1  (a notification — one line diff)
you run /rhiza:update
/rhiza:update applies the new CI files, linting config, etc. in a PR

Two separate steps: should we upgrade? (the ref-bump PR) then here's what changed (the /rhiza:update PR).
Opt-in per repo. Systematic across the organisation.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Part 4

Getting Started

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Four commands

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

# 2. Make the repo rhiza-managed — writes .rhiza/template.yml, opens PR #1
/rhiza:init

# 3. After #1 merges: sync the template — this is where the files arrive (PR #2)
/rhiza:update

# 4. Install dev environment
uv run rhiza-task install     # or: make install

The /rhiza:* commands come from the rhiza Claude Code plugin — install it once with
/plugin marketplace add Jebel-Quant/rhiza-claude then /plugin install rhiza@rhiza-claude.

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

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

What you get on day one

After syncing with the github-project profile (core + python-core + github + book and their GitHub overlays):

.github/workflows/rhiza_ci.yml          ← CI: test matrix on push and PRs
.github/workflows/rhiza_release.yml     ← Build + publish to PyPI on a tag
.pre-commit-config.yaml                 ← Local commit hooks (rhiza-hooks, run by prek)
ruff.toml                               ← Linting config
Makefile                                ← 71-line shim: pins RHIZA_TASK, forwards to it
.python-version                         ← Pinned Python version
.editorconfig                           ← Editor consistency

Config files, all of them. The tasks behind make test come from rhiza-task, fetched by uvx at the pinned version — not copied into your repo.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Part 5

Living with Rhiza

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

Customising safely

Need Mechanism
Your own make targets local.mk-included, never synced
How a task behaves (folders, typechecker, thresholds) [tool.rhiza-task] in pyproject.toml
A native binary every gate needs Executable local-setup.sh at the repo root
A per-developer setting override .rhiza/.env (gitignored)
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. Since v1.5.0 check-managed-files
refuses the commit — so you find out now, not in the next sync PR.

(custom-task.mk and custom-env.mk retired with the make layer in v1.4.0.)

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Part 6

The Ecosystem

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

The Rhiza ecosystem

Tool What it does
rhiza-claude Claude Code plugin — the /rhiza:* command set (init, update, quality, docs, release, remote, status, completions, detach, maffay). The primary interface.
rhiza-task The developer tasks as a pinned CLI — what make test actually runs
pytest-rhiza The repository conformance checks, as a pytest plugin
rhiza-hooks Commit hooks (run via prek): validate config, check version consistency
rhiza-brainbug Cross-repo test harness: runs contract tests on upstream commits
Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

Who's using it

The Rhiza tools themselves — rhiza and rhiza-hooks sync from the template; rhiza-claude and rhiza-task run its gates through the pinned CLI. The system eats its own cooking.

External projects:

Project Organisation Config
simulator Stanford CVXGRP github-project + legal
jsharpe tschm github-project + legal
chebpy chebpy github-project + devcontainer + github-paper
loman Janus Henderson hand-listed bundles, several releases behind

Three of the four have converged on profile + a short list of extras.

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0

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 v1.7.1 / rhiza-claude v0.13.0

Get started

/rhiza:init

ῥίζα (ree-ZAH) — root

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

Rhiza — The Living Template System · jebel-quant.github.io/rhiza-education · rhiza v1.7.1 / rhiza-claude v0.13.0