2026-06-19T02:18:45Z by Showboat 0.6.1
cookiecutter to conformanceOne command turns nothing into a tenant the platform already trusts.
chimpy-lake is the scaffold — the platform repo that
holds the catalog substrate, the lifecycle SDK, the telemetry hub, the
plugin contract, and the cookiecutter templates that
mint new tenants. Onboarding a data source shouldn’t be tribal
knowledge; it should be generation plus a gate. If you’ve run
npm create, cargo new, or
create-react-app, you already know the shape: one command,
a correct skeleton, ready to fill in.
This walkthrough follows one tenant from a single command to passing the live contract, and shows the provenance stamp that keeps a generated tenant honest about which platform version made it. Every beat runs the real cookiecutter, the real validator, and the real conformance suite against a tenant generated into a throwaway directory.
What. A new tenant starts as a
cookiecutter render — a runnable skeleton conforming to the
plugin contract, not a blank repo.
Why it matters. The correct shape is the default: manifest, entry point, Quadlet stub, and conformance test are all there from the first commit.
How we do it — generate one and list what landed:
uv run python docs/demos/scaffold-a-tenant/_driver.py generate
Generate — one command, a fresh tenant repo
===========================================
$ cookiecutter templates/tenant-extract (tenant_name=demo-tenant)
generated repo: cl-extract-demo-tenant/
.env.example
.gitignore
Dockerfile
Makefile
README.md
app.py
chimpy-tenant.toml
docker-compose.yml
pyproject.toml
quadlet/<host>/cl-extract-demo-tenant.container
sql/.gitkeep
systemd/<host>/cl-extract-demo-tenant.timer
tests/test_contract_conformance.py
tests/test_smoke.py
The blueprint is real: a runnable tenant skeleton, contract-shaped from line one.
What. The generated chimpy-tenant.toml
is a Tier-3 manifest (it has the
[lifecycle] section the control plane operates)
and a [scaffold] section recording which
chimpy-lake version minted it.
Why it matters. Provenance is first-class: the platform can later see, per tenant, which version it came from — and it validates against the live Tier-3 validator, so a generated tenant is conformant by construction.
Term to know: provenance; Tier-3 (contract + lifecycle).
How we do it — parse the generated manifest with the real validators:
uv run python docs/demos/scaffold-a-tenant/_driver.py manifest
Manifest — Tier-3 + version provenance, validated
=================================================
tenant.name demo-tenant
tenant.kind extract
lifecycle.subcommands ['run', 'status', 'dry-run', 'migrate']
scaffold.template tenant-extract
scaffold.chimpy_lake_version 0.2.0
It passes the live Tier-3 validator, and it records WHICH platform version
scaffolded it — provenance baked into the contract, not lost to tribal memory.
run(); the SDK gives you the restWhat. The generated app.py wraps the
tenant’s own run() in LifecycleApp, which
supplies the uniform status / dry-run /
migrate verbs.
Why it matters. The only tenant-specific code is the extract logic. Every verb the control plane relies on is inherited — uniform across all tenants.
How we do it — inspect the generated entry point:
uv run python docs/demos/scaffold-a-tenant/_driver.py app
app.py — you write run(); the SDK gives you the rest
====================================================
supplies its own run() True
wraps it in LifecycleApp True
inherits for free: status / dry-run / migrate (SDK defaults)
The one tenant-specific thing is the extract logic inside run(). Every other
verb the control plane relies on comes from the SDK — uniform across all tenants.
What. chimpy-lake ships a conformance suite that a tenant must pass: its manifest validates, the telemetry SDK imports, a Quadlet stub is present, and the app runs.
Why it matters. “Conforming” isn’t a promise — it’s a test that runs. Here it runs against a tenant that was generated seconds ago, with nothing hand-edited.
Term to know: conformance gate (the single CI gate that proves cookiecutter + validator + plugin contract all interlock).
How we do it — run the real suite against the freshly generated tenant:
uv run python docs/demos/scaffold-a-tenant/_driver.py conform
Conform — the live gate runs against a 30-second-old tenant
===========================================================
...s. [100%]
4 passed, 1 skipped
4 passed, 1 skipped — the one skip is the container-image presence check
(we don't build the image for the demo). A tenant that didn't exist a moment
ago already satisfies the manifest contract, imports the telemetry SDK, and
ships a Quadlet stub.
What. The
[scaffold].chimpy_lake_version stamp equals chimpy-lake’s
own version, and a CI guard asserts it — bump the platform without
bumping the template and the build goes red.
Why it matters. Provenance is only useful if it’s true. The lockstep guard makes drift unmergeable, so the stamp is always trustworthy.
Term to know: lockstep (template ↔︎ contract ↔︎ version, enforced by CI).
How we do it — compare the stamp to the live platform version:
uv run python docs/demos/scaffold-a-tenant/_driver.py lockstep
Lockstep — the stamp can't drift from the platform
==================================================
scaffolded tenant stamp chimpy_lake_version = 0.2.0
chimpy-lake pyproject version = 0.2.0
in lockstep? True
A CI guard (test_cookiecutter_template) asserts these are equal — bump the
platform without bumping the template and the build goes red. Provenance you
can trust, because drift can't merge.
Every command above re-runs under showboat verify. And
the thesis — a generated tenant is Tier-3, version-stamped, and passes
the live gate — ships green:
uv run pytest tests/demos/test_scaffold_a_tenant.py -q 2>&1 | sed -E 's/ in [0-9.]+s//'.. [100%]
2 passed
chimpy-tenant.toml) — a
tenant’s declared, validated shape. (Beat 2)[scaffold] — the record
of which chimpy-lake version minted a tenant. (Beat 2)run/status/dry-run/migrate
verbs. (Beat 3)Three directions the provenance stamp unlocks but that are not built:
doctor could warn
when a deployed tenant trails the current contract — drift you can see,
not discover.tenant-extract is one
template; a tenant-report (read-the-lake, produce
artifacts) would scaffold the other half of the contract.Nothing exotic — one command, a gate, and a stamp that can’t lie. Everything above re-runs on demand.
← all walkthroughs · Rendered from e906d4b on 2026-06-19 · showboat verify: reproduces. A living artifact — the version ledger is git.