Yanjú
Yanjú (Yoruba for "to solve" / "bring order to chaos") is a local, disposable debugging harness. It drops engineers into containerized, intentionally broken apps so they can practice reading logs, fixing config, and shipping a working service — not trivia.
v0.1 points at yanju-scenarios: broken-proxy (Nginx → FastAPI under k6 load) and broken-playbook (Ansible deploys a Jinja nginx template onto a web host). The CLI does not ship scene files; it fetches a scene folder and copies only the editable surface into your working directory.
Requirements
- Python 3.11+
- Docker Engine with Compose v2 (
docker compose)
Install
uv tool install yanju
# or: python3 -m pip install yanju
The wheel is the CLI engine only. Scene files come from yanju-scenarios at runtime (or a local checkout).
Quick start
yanju check
yanju scene # or: yanju scene --all then yanju init broken-proxy
yanju play
Edit the copied files in your IDE. Re-run yanju play after config changes so the stack recreates and hidden tests run. Use --persist to leave the stack up while you debug. Then:
yanju status
yanju verify
yanju reset
init copies the editable surface into the current directory (for broken-proxy: app/, nginx/, compose; for broken-playbook: app/, ansible/, compose) and writes a README from brief.problem / brief.outcome. Hidden eval/ tests, the k6 overlay, and lab SSH keys stay in the scene checkout (cache or local yanju-scenarios/), not in your cwd.
Commands
| Command | What it does |
|---|---|
yanju check |
Docker ping, RAM/CPU (warn below 2 GB / 2 CPUs). Pulls images for the current workspace scene if one is initialized |
yanju init <scenario> |
Copy workspace, git init + baseline commit. --force stops the previous stack, then replaces the workspace |
yanju scene |
List the catalog (index.yaml) and pick one to initialize. --all lists without initializing |
yanju play |
Start or recreate the stack, run hidden tests, stop containers if they fail. Logs stay at .yanju/logs/stack.log. --persist leaves the stack running (previous default). --follow streams logs after the stack stays up |
yanju help |
How to apply edits, logs, and verify |
yanju logs |
Tail captured logs (Ctrl+C detaches). --no-follow for a one-shot dump |
yanju status |
Container health, ports, CPU/memory, whether k6 is running |
yanju verify |
Hidden pytest against the scenario verify.base_url plus a git diff. PASS/FAIL is tests only; app/ edits warn |
yanju stop |
compose down -v; keep workspace files and .yanju/ logs |
yanju reset |
compose down -v, restore files to the init commit, keep .yanju/ |
Scenes
Scenes live in a separate yanju-scenarios catalog, not this package. Yanjú reads index.yaml, fetches that scene folder, and copies workspace.copy into cwd.
A source checkout of this repo uses ./yanju-scenarios when present. Otherwise the CLI clones the remote in yanju/catalog.yaml. Overrides:
YANJU_SCENES_DIR— path to a local checkoutYANJU_SCENES_REPO/YANJU_SCENES_REF— git URL and branch/tag to clone into~/.cache/yanju/scenes/(orYANJU_SCENES_CACHE)
Default remote: https://github.com/xyluz/yanju-scenarios.git.
Adding a scenario
Add a folder to yanju-scenarios (not this CLI) with:
scenario.yaml— name, brief.problem, brief.outcome, images,workspace.copy, compose project, health service, verify URL, optional chaos commanddocker-compose.yaml— the whole stack (PHP-FPM, MySQL, Redis, … are fine)- files listed in
workspace.copy - optional
docker-compose.k6.yamloverlay (not copied to the candidate) - optional
chaos/hook eval/pytest files that readYANJU_BASE_URL- a row in
index.yaml
The harness never imports scenario Python and never assumes FastAPI or Nginx.
Development
python3 -m pip install -e ".[dev]"
python3 -m pytest tests -v
The default suite does not need Docker.
Release files for yanju 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| yanju-0.1.1.tar.gz | 25.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| yanju-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.8 kB
Release files / yanju-0.1.1.tar.gz
| Download URL | yanju-0.1.1.tar.gz |
|---|---|
| Size | 25.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e1666b4f81e6fb136bc95c16e3aba3be13034dc99402d288801a0221de4672ae
|
|
BLAKE2b-256 checksum How to use checksums |
fea8973b6454974ae9ddc846418a8a365c2b50474ef125f6a2e6d7a8a2fc98c2
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / yanju-0.1.1-py3-none-any.whl
| Download URL | yanju-0.1.1-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a806c03a825efa4033971f6c6bff2cb8f94b8c277e781cdb5b98016c461ef6c7
|
|
BLAKE2b-256 checksum How to use checksums |
e552b0cca7d0a0fb5e26203032ca3369f81e001fb2cd3424b069d3ec39a28a75
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|