Den v0.18 Release Notes
✨ Major Features
1. Gen-schema entity port + resolver/delivery unification (#563)
Five-part stabilization reaching 1023/1023 tests (from 825 at branch start):
- Entity schema refactor:
den.schemamigrates to gen-schema'smkSchemaOption/mkSchemaEntryType. Entities ownid_hashviamkInstanceType. Flat declaration forms (den.hosts.igloo = {},den.homes."tux@igloo" = {}) coexist with legacy two-level nesting. - Isolation + delivered-child host: microvm guests. Kind-level
isolatedmarker, re-instantiating payload delivery, projectedhasAspectre-keyed by entityid_hash(fixes nested host false-negatives). - Resolver decoupling: Pure arg classifier over schema entity DAG. Removes host/user-specific machinery from fx resolver core. Fixes host-scope
{ user }homeManager aspects leaking to all users (#609). - Delivery-edge unification: Nine ad-hoc mechanisms collapse to one
(S, T, P, M)edge algebra. Newdeliver { from; to; at ?[]; mode ? "merge" }primitive;routeandprovidesretained as thin shims. One toposorted edge-fold per root. - Constraint registry unification + sibling-exclusion fixes: sibling
excludesno longer leak across entities. Unified scope+ancestor constraint lookup; late-policy dispatch scopes to emitting sibling.
Breaking change: Entity-arg binding now scoped (inert if not in-context). Cross-entity delivery via provides/policy only. Documented in explanation/parametric.mdx.
2. Synthesize host identity for standalone user@host homes (#605)
Standalone home user@host now resolves host-keyed config (provides.<host>, policy.when ({ host })) without declaring the host or instantiating platform builder. Minimal { name = hostName } identity synthesized; declared host still wins.
Fixes crash in related include-return path: aspects returning include-effect lists (e.g. lib.optional cond (policy.include {...})) now normalized (lists flattened, effects pass through).
3. In-context hasAspect honors projected scope state (#602)
.hasAspect inside parametric bodies now answers projected membership ("delivered into this scope") vs structural tree. Registry query (den.hosts.….users.tux.hasAspect) stays structural. Per-scope pathSetByScope recorded; zero extra pipeline runs.
🐛 Major Fixes
Resolver & delivery pipeline
- Sibling policy.when guard dedup collision (#603): Guards compile to anonymous aspects; dedup now indices synthetic names and chains payloads, preventing second guard's content vanishing.
- Spawn subtree routes (#603): Parent pipeline routes now apply to spawned resolution; user-scope route no longer skipped in spawn re-entry.
- Multi-def forwarded identity (#603): Multi-def namespace children now tagged with
__provider, fixing double-emission from multi-path inclusion. - Guarded route crashes (#600):
intoPathalias honored; guarded empty-path routes now skip cleanly withoptionalAttrs(notmkIf). - Positional context functions in includes (#578):
ctx: ...functions (empty args) now routed to parametric compile and called with full scope context, not silently dropped.
Forward routing & class merging
- Forwarded content overwritten across scopes (#583): Root content in complex forwards no longer filtered to
@default-only when not an entity-owned class. Fixes cross-scope aggregation (e.g. atuin flags merging). - Route wrapping merge semantics (#574): Multiple aspects defining same flake class no longer clobber. Routes toposorted (producers before consumers);
mergeableTypedeep-merges instead of shallow//. - Order simple routes before forwards (#584): Routes applied in correct order; custom forwards consume class content correctly.
Config & module handling
- Don't force aspect content during key classification (#580): Lazy instantiation preserved in compile-static; no forced evaluation during structural key walk.
- Resolve positional functions with scope context (#578): Direct lambda detection +
ctxFromHandlerscall instead offx.bind.fn. - Null coercion in warning messages (#576): Explicit
ifcheck replacesor; no morecannot coerce nullon multi-system homes with null system.
Entity & output handling
- Disambiguate multi-system homes (#565): Same user on multiple systems auto-qualified
@system(homeConfigurations."ben@x86_64-linux"/homeConfigurations."ben@aarch64-darwin"). Single-system homes keep plain name. - Correct flake output include schema kind (#587): Example corrected to
flake-system(not non-existentflake-packages). - Remove __denTest hack (#571): Test harness cleanup.
- Missing host class in batteries (#606):
host ? classcheck prevents unfree battery crash when host lacks class.
Schema & validation
- Flattening default den.schema (#616): Fixes Lix runtime (other nix runtimes) unable to merge multiple attrs same name in different brackets.
🎨 Refactors & Chores
- Extract diagram library to sini/den-diagram (#564):
nix/lib/diag/→ den-diagram repo. Den keeps onlycapture.nix(fx tracing). Templates (diagram-demo, fleet-demo) use two-step pattern. Den CI has zero den-diagram dependency. - Organize tests: public-api/internal-api/deadbugs (#592): Test suite restructured; CI test org documented.
- Backport aspect-pipeline fixes (#589): Cherry-picks + one net-new (namespace root
_bundle). Namespace-root_exposes container-level aspects (flat map, no recursion). - Performance: break closure chains and lazy instantiation (#579): Backport; reduced evaluation overhead.
- CI: bump nix-effects to den branch (#529): Dependency update.
📖 Documentation
- Remove deprecated link (#612): Archived repository pattern removed.
- Update links & README (#595, #594): Examples simplified, links corrected.
- Update docs from source (#593): Docs refreshed.
- Fix typos (#597).
- GH-pages robustness (#591): Artifact listing paginates; no longer caps at 30 (silent truncation).
✅ CI & Testing
- Live label queries, real allow-ci gating (#607): Label checks now query API (see re-run labels);
ci-deep/flake-checkactually gated; main builds never cancelled;non-draftskip cleanly on docs-only PRs; approved reviews only re-trigger CI.
What's Changed
- fix: disambiguate multi-system homes targeting same homeConfigurations output by @sini in #565
- fix: remove __denTest hack by @vic in #571
- ci: bump nix-effects to den branch by @vic in #529
- fix: route wrapping merge semantics and forward ordering by @sini in #574
- fix: null coercion in disambiguate warning message by @sini in #576
- fix: don't force aspect content during key classification (#580) by @sini in #581
- perf: break closure chains and lazy instantiation backport by @sini in #579
- fix: resolve positional functions in includes with scope context by @sini in #578
- fix: forwarded content overwritten across scopes (#583) by @sini in #585
- fix: correct flake output include to flake-system schema kind by @sini in #587
- fix: backport aspect-pipeline fixes from entity-gen-schema-port by @sini in #589
- fix: order simple routes before forwards that consume their class by @sini in #584
- fix: gh-pages dont fail if no cached versioned docs exist by @vic in #591
- improve: organize tests public-api/internal-api/deadbugs by @vic in #592
- docs: update docs from source by @vic in #593
- docs: update README remove extensive code examples by @vic in #594
- docs: update links by @vic in #595
- refactor: Extract diagram library to sini/den-diagram by @sini in #564
- docs: fix some typos by @quokkbit in #597
- fix: guarded empty-path route skips cleanly; honor intoPath alias by @sini in #600
- feat: in-context hasAspect honors projected (delivered) scope state by @sini in #602
- fix: sibling policy.when guard dedup collision; spawn subtree routes; multi-def forwarded identity by @sini in #603
- fix: move deadbug to proper location by @vic in #604
- feat: synthesize host identity for standalone user@host homes by @sini in #605
- fix: missing host class in batteries by @KP64 in #606
- fix(ci): live label queries, real allow-ci gating, dead triggers by @sini in #607
- fix(docs): Remove deprecated link by @Adda0 in #612
- feat: gen-schema entity port + resolver decoupling + delivery-edge unification by @sini in #563
- fix: flattening default den.schema by @fmway in #616
New Contributors
- @quokkbit made their first contribution in #597
- @KP64 made their first contribution in #606
- @fmway made their first contribution in #616
Full Changelog: v0.17.0...v0.18.0