Configuration as data
When an Arch update on a Tuesday morning requires a new workaround for a specific Intel iGPU — what does a traditional installer do? Nothing, until somebody patches the bash script that drives it, releases a new ISO (1–3 GB), and waits for users to download it. Days at best, weeks more commonly.
Ditana takes a fundamentally different approach: configuration as data.
Two separate pieces
Section titled “Two separate pieces”Ditana’s architecture is strictly divided into two repositories:
- The Engine (
ditana-installer) — a small, generic program that knows how to draw dialogs, partition disks, detect hardware, and runpacstrap. - The Knowledge Base (
ditana-config) — a structured database written in KDL v2. It declares every setting, every hardware quirk, every package dependency, every lifecycle script, and the logical relationships between them.
When you boot the Ditana ISO, the engine connects to GitHub and downloads the latest release of the knowledge base (falling back to an offline snapshot bundled with the ISO if you have no internet connection).
Why this matters
Section titled “Why this matters”Three benefits, in order of immediate impact:
- Zero-respin updates. If a user reports that a recent Arch update requires a new workaround, the fix lands in
ditana-configas a small KDL edit. The very next person who boots a Ditana ISO downloads the updated logic automatically. The fix reaches users immediately, without anyone needing to download a new 2.6 GB ISO. - Transparent reasoning. Because settings are declared as structured data with explicit conditions, the rules are auditable end-to-end. Anyone can read the KDL files and see exactly why a package is installed, what combination of settings triggers a configuration file to be deployed, or which hardware property gates an option. No bash detective work.
- Forkable contributions. Adding a hardware workaround, a new desktop tweak, or a packaging choice usually means editing a single KDL file. No installer engine changes, no Raku knowledge required. The
ditana-configREADME walks contributors through the schema; most pull requests touch one file.
Why KDL, not JSON or YAML
Section titled “Why KDL, not JSON or YAML”The knowledge base could have been any structured format. KDL was chosen because it has the properties Ditana’s configuration actually needs:
- Native comments. YAML and JSON both struggle here — YAML has comments but tooling support is uneven; JSON has none at all. Ditana’s settings include extensive rationale comments explaining why a default is what it is. Those comments are the point.
- Raw strings. Embedded shell snippets, sed expressions, and regex patterns are first-class. No double-escaping
"and\to satisfy the parser. - Hierarchical without ceremony. Children, properties, and arguments coexist cleanly. The same node can describe a setting and contain sub-nodes for its packages, scripts, and files.
- Diff-friendly. Insertion order is preserved. A code review of a one-line addition shows a one-line diff, not a reordered structure.
The format is parsed by a small Rust converter (json-kdl-converter, also versioned alongside the schema) before the Raku installer consumes it as JSON. The next section explains how the data is validated end-to-end before any of that.
What this looks like in practice
Section titled “What this looks like in practice”A complete, working setting in ditana-config looks like this:
- name="install-bubblewrap-suid" \ default-value="`(flatpak OR install-bubblejail) AND (kernel-option-duurn OR install-hardened-stable-kernel)`" { // Without this, every Flatpak fails at startup // with "bwrap: No permissions to create a new namespace". arch-packages "bubblewrap-suid" }That node declares a derived setting (no user-facing dialog), a logical expression over four other settings, and one package to install if the expression is true. The reasoning lives next to the rule, where someone reviewing it can see why. The full schema documentation is in the ditana-config README.
Validation: catching mistakes before they ship
Section titled “Validation: catching mistakes before they ship”A knowledge base this large needs guardrails. Every commit — both locally via pre-commit hooks and remotely on GitHub Actions — runs a layered validation pipeline that catches the mistakes a human reviewer might miss:
- KDL syntax (
kdlfmt) — the file parses at all. - Schema validation (
ditana-schema.json) — every field has the right type, no unknown properties, no missing required fields. Catches typos in field names likearc-packagesinstead ofarch-packages. - File reference integrity — every file referenced from a setting actually exists in
folders/; conversely, every file infolders/is referenced by at least one setting. Orphans get flagged. Directory references (which would silently do nothing because the installer usescpwithout-R) are rejected. - Lifecycle correctness —
chroot-scriptlines that touch/etc/skel/are rejected, because the user is created afterchroot-scriptruns — the correct field isearly-chroot-script. A subtle bug that would otherwise produce a system where the new user’s home doesn’t have the expected files. - Shell script validity — every shell snippet in any of the script-list fields gets
bash -nfor syntax andshellcheckfor quality. Same for standalone scripts underfolders/. A missing quote or a[ "$x" = $y ]style bug gets caught at commit time, not at first install. - Logical expression integrity — backticks must balance; every setting name referenced in a
default-valueoravailableexpression must actually exist somewhere in the knowledge base. A typo likeinstall-cosmikinstead ofinstall-cosmicgets caught at commit time instead of producing a silent runtime crash.
The full check runs in seconds locally with pre-commit run --all-files, and again on every push to GitHub. Local green means CI green; broken commits never make it to a release.
Where to go next
Section titled “Where to go next”- Browse the
ditana-configrepository to see how the rules are organised by dialog and topic. - Read the
ditana-configREADME for the data model: how settings, scripts, dialogs and files relate. - Look at the
ditana-installersource if you want to see the engine that reads and acts on the configuration.