Architecture
Overview
ddl is a thin orchestrator that delegates to existing tools and package managers. It does not reimplement package resolution, tool commands, or database management.
Key design decisions
Subprocess protocol over shared library linking
ddl communicates with each tool via subprocess calls (wai status --json,
dont status --json). This decouples release cycles — a genesis breaking
change doesn’t require coordinated releases of ddl + all 9 other tools.
Fallback installation chain
Binary download → cargo install (only when a release binary is unavailable and cargo is present; npm for incitaciones). Homebrew and Scoop are no longer part of ddl’s install decisions — the tap and bucket remain published for manual installs only.
Binary downloads are the most reliable path (no dependencies). Cargo install is the fallback when no release binary is available and cargo is installed. Brew/scoop are not used by ddl for installs (see DDL-ei3).
Phase 1: Symlink farm
Before deep genesis integration, ddl uses a symlink farm: each tool’s
legacy config directory stays at its old path but becomes a symlink into
.ddl/ (the backing store):
.wai/→.ddl/wai/(symlink).dont/→.ddl/dont/(symlink)- etc.
No tool patches needed. Zero risk — symlinks are transparent to file reads.
Phase 2: Native config proxy
Each tool learns to check .ddl/<tool>/ first via genesis. Requires
coordinated releases of each tool.
Directory layout
.ddl/
manifest.json # {"ddl_version": "0.3.0", "migration_state": "...", "tools": {...}}
config.toml # ddl's own config
compatibility-cache.json # cached compatibility matrix
wai/ # wai config files
dont/ # dont config files
ah/ # ah config files
pretender.toml # pretender config file
testaruda/ # testaruda config files
vampiro/ # vampiro config files
specodelic/ # specodelic config files
Legacy directories become symlinks pointing to .ddl/:
.wai/ -> .ddl/wai/ # symlink to .ddl/
.dont/ -> .ddl/dont/ # symlink to .ddl/
.espectacular/ -> .ddl/ah/ # symlink to .ddl/
.pretender.toml -> .ddl/pretender.toml # symlink to .ddl/
.testaruda/ -> .ddl/testaruda/ # symlink to .ddl/
.vampiro/ -> .ddl/vampiro/ # symlink to .ddl/
.specs/ -> .ddl/specodelic/ # symlink to .ddl/
Data flow for ddl status
ddl status
→ reads config from .ddl/config.toml
→ for each registered tool:
→ loads tool config from .ddl/<tool>/
→ runs tool's status command (subprocess)
→ parses output
→ collects result
→ renders aggregate status report
Platform strategy
| Platform | Primary installer | Fallback |
|---|---|---|
| macOS (ARM) | Binary download | Cargo install |
| macOS (Intel) | Binary download | Cargo install |
| Linux (ARM) | Binary download | Cargo install |
| Linux (Intel) | Binary download | Cargo install |
| Windows | Binary download | Cargo install |
incitaciones always installs via npm. Tools without published release
binaries require cargo on the machine.