diff --git a/tech_docs/docker_compose_guide.md b/tech_docs/docker_compose_guide.md index f11499f..05caf66 100644 --- a/tech_docs/docker_compose_guide.md +++ b/tech_docs/docker_compose_guide.md @@ -32,7 +32,7 @@ serendipity/ ### 2. The Royal Charter (`kingdom.yml`) -```yaml + kingdom: # determinism knobs seed: 42 @@ -53,7 +53,7 @@ kingdom: to: stdout - format: yaml to: out/kingdom_rendered.yaml -``` + Nothing outside this file ever changes the deterministic output except the **seed**. @@ -63,12 +63,12 @@ Nothing outside this file ever changes the deterministic output except the **see Every object **MUST** be valid YAML and **MAY** include Jinja2 expressions inside **quoted** scalars only. -```yaml + # objects/unicorn.yaml id: unicorn color: "{{ rng.choice(['silver','iridescent']) }}" blessing: "{{ magic.uuid4() }}" -``` + Important: - Expressions are **strings** → safe for YAML parsers. @@ -78,7 +78,7 @@ Important: ### 4. The Single Rulebook (`rules/resolve.j2`) -```jinja2 + {#- 1. Bootstrap deterministic engines -#} {% set rng = load_rng(kingdom.rng) %} {% set magic = load_magic(kingdom.magic) %} @@ -93,7 +93,7 @@ Important: {#- 3. Emit final deterministic YAML -#} {{ court | to_yaml }} -``` + Helper filters (`load_rng`, `load_magic`, `glob`, `read_file`, `render_str`) are registered once at startup; **they never change** and are **not serialisable**, so they cannot leak into objects. @@ -101,7 +101,7 @@ Helper filters (`load_rng`, `load_magic`, `glob`, `read_file`, `render_str`) are ### 5. Bootstrap Script (one-time, never edited) -```python + #!/usr/bin/env python3 # bootstrap.py (kept outside kingdom/) import os, yaml, jinja2, glob, hashlib, random @@ -128,7 +128,7 @@ env.globals.update({ template = env.get_template('resolve.j2') print(env.from_string(template.render(kingdom=meta['kingdom'])).render()) -``` + Run once → deterministic stream of bytes. Commit the stream if you need reproducibility without Python. @@ -169,11 +169,11 @@ Commit the stream if you need reproducibility without Python. ### 9. Single-Command Invocation (CI / Makefile) -```makefile + render: @python bootstrap.py > kingdom_rendered.yaml @echo "SHA256: $$(sha256sum kingdom_rendered.yaml)" -``` + --- @@ -187,7 +187,7 @@ render: Here is a **drop-in Jinja2 template skeleton** that turns the entire service stanza into variables you can override at render-time (`docker compose -f <(jinja2 compose.yml.j2 env.yml)` or `docker compose config`). You only need to set the variables you care about; everything else falls back to safe blanks or defaults. -```jinja2 + # compose.yml.j2 services: {{ service_name | default("app") }}: @@ -316,11 +316,11 @@ services: {{ k }}: {{ v }} {% endfor %} {% endif %} -``` + Usage example with a tiny `env.yml`: -```yaml + # env.yml service_name: api image: mycorp/api:1.4.2 @@ -334,13 +334,13 @@ volumes: depends_on: - db restart: always -``` + Render and validate: -```bash + jinja2 compose.yml.j2 env.yml | docker compose -f - config # dry-run -``` + All other knobs (secrets, configs, devices, ulimits, etc.) can be added the same way—only when you need them.