Skip to content

Instantly share code, notes, and snippets.

View sini's full-sized avatar

Jason Bowman sini

  • San Francisco, CA, USA
View GitHub Profile
@sini
sini / 2026-05-12-fleet-demo-user-registry-design.md
Last active May 12, 2026 20:27
Fleet Demo: User Registry & Policy-Driven Access - Design Spec

Fleet Demo: User Registry & Policy-Driven Access

Date: 2026-05-12 Status: Draft

Summary

Replace the fleet demo's inline users.deploy = { } host definitions with a standalone user registry (den.users.registry) and fleet-level access mappings (fleet.user-access). Users are defined once with extended schema (email, groups, ssh-keys), then policies resolve them onto hosts based on environment or host-level group membership.

Motivation

@sini
sini / 2026-05-14-builtin-flake-parts-entity-design.md
Created May 14, 2026 20:26
Design spec: Built-in flake-parts entity kind for den

Built-in flake-parts Entity Kind

Context

Users want to write to top-level flake-parts config paths (outside config.flake) from aspects — e.g., config.inputs, config.perSystem.packages, config.treefmt. The flake-parts-modules template demonstrates this is possible via a custom flake-parts entity with scope transition and manual resolution, but it requires ~80 lines of boilerplate that users must replicate.

Host, user, and home entities are built-in. The flake-parts entity should be too.

Goal

@sini
sini / 2026-05-14-pipeline-reference.md
Created May 14, 2026 21:13
Den FX Pipeline Reference — handlers, effects, scope management, routing, dedup, policy dispatch

Den FX Pipeline Reference

Den's FX pipeline is the core resolution engine that transforms declarative aspect definitions into NixOS/nix-darwin/home-manager module trees. It operates as an algebraic effects trampoline -- a loop that interprets effect values, dispatches them to handlers, and threads state through each step. Every state change is an effect; pure data transforms stay as functions.

This document covers the pipeline lifecycle from entity entry through final output assembly.

1. Pipeline Overview

The pipeline resolves a single entity (flake, host, home, user) by walking its aspect tree. Each aspect is compiled according to its shape, gated for dedup and constraints, classified into output buckets, emitted as class modules, and then its children (includes, policies) are recursively resolved. The result is a set of NixOS-style module lists keyed by class name.

@sini
sini / flake-parts.nix
Last active May 14, 2026 22:53
Adapted test: routing aspect content to top-level flake-parts config via built-in entity
# Routing aspect content to arbitrary top-level flake-parts config paths.
#
# Pattern: route into "flake" class with any path, read via den.lib.flakeRouted.
#
# Three pieces:
# 1. den.classes.X — register a class for the content
# 2. den.lib.policy.route { intoClass = "flake"; path = [...]; } — pipeline wiring
# 3. config.Y = den.lib.flakeRouted.Y or {}; — deliver to top-level option
#
# No extra pipeline. No cycle. Lazy config assignment.
@sini
sini / 2026-05-19-hoag-pipeline-architecture.md
Last active May 20, 2026 00:09
Den Pipeline Architecture: Demand-Driven Attribute Grammar over Scope Graphs

Den Pipeline Architecture: Demand-Driven Attribute Grammar over Scope Graphs

Den resolves declarative aspect configurations into per-entity NixOS module lists. This is an attribute grammar evaluation problem: a tree of entities (the scope graph) carries attributes (aspect content) that flow top-down (inherited), bottom-up (synthesized), and laterally (via import edges). Predicated semantic rules (policies) can create new scope nodes mid-evaluation.

This document defines Den's pipeline — how Den wires scope-engine, den-schema, and flake-aspects with den-specific attribute definitions, policy semantics, and output assembly. It does not define the generic evaluator (see companion spec).

Companion specs:

  • scope-engine — the generic HOAG evaluator library (algebraic graphs, evaluator, scope queries, attribute constructors)
  • flake-aspects — the aspect type system (three-branch dispatch, identity, includes, sidecar
@sini
sini / 2026-05-19-den-schema-hoag-integration.md
Last active May 19, 2026 23:41
den-schema Integration with HOAG Pipeline

den-schema Integration with HOAG Pipeline

Companion to: HOAG Pipeline Architecture

den-schema (github:denful/den-schema) provides the entity data model — kinds, instances, identity hashing, validation, cross-references. This document specifies what den-schema provides to the HOAG pipeline, what gaps exist, and how the integration bridge works.

What den-schema Provides (No Changes Needed)

Entity Kinds and Instances

@sini
sini / 2026-05-10-aspects-lib-extraction-design-revised.md
Last active May 19, 2026 23:41
flake-aspects Library Extraction (Final) — Den Aspect Type System Spec

Aspects Library Extraction (Final)

Extract den's aspect type system into a standalone library — a successor to flake-aspects with nested aspect support, built-in identity, unified module key typing, and schema extensibility. Developed inside den at nix/lib/aspects2/, later extracted to its own repo with flake-aspects' git history preserved.

Companion specs:

  • den-schema (github:denful/den-schema) — standalone schema library providing sidecar extraction, strict mode, identity hashing, methods, and instance registries. The aspects library adopts den-schema's sidecar extraction pattern; the two libraries are independent but composable.
  • HOAG Pipeline Architecture — the demand-driven attribute grammar evaluator that consumes flake-aspects as its content data model. flake-aspects provides three native aspect shapes; the HOAG pipeline adds a fourth (conditional) via the schema extension mechanism. flake-aspects' resolve output is wrapped by the pipeline to atta
@sini
sini / 2026-05-19-scope-engine-design.md
Last active May 19, 2026 23:41
scope-engine: Demand-Driven HOAG Evaluator over Algebraic Scope Graphs

scope-engine: Demand-Driven Attribute Grammar Evaluator over Algebraic Scope Graphs

A minimal Nix library (~200-350 lines) for demand-driven evaluation of attribute grammars over scope graphs composed algebraically from independent module declarations. Leverages Nix's native lazy evaluation for attribute computation, memoization, and cycle detection.

scope-engine is a hybrid HOAG/RAG evaluator: Higher-Order AGs (Vogt et al., 1989) for dynamic node synthesis, Reference AGs (Hedin, 2000) for cross-node references via import edges. Import edges step outside strict HOAGs (where information flows only along the tree structure) into RAG territory (where attributes can reference arbitrary other nodes). Hedin formalizes that fixed-point evaluation over these cross-edges terminates when attribute functions are monotonic.

scope-engine is generic — it has no knowledge of NixOS, aspects, policies, or system configuration. It provides the evaluation machinery; consumers define what to compute. scope-engine has **

@sini
sini / 2026-05-22-nest-traits-on-gen-stack-design.md
Created May 22, 2026 17:56
Nest traits model on gen-schema + gen-aspects + scope-engine — design spec

Nest Traits Model on gen-schema + gen-aspects + scope-engine

Date: 2026-05-22 Status: Design approved Location: scope-engine/templates/nest-traits/

Goal

Proof-of-concept that nest's traits model can be rebuilt on gen-schema + gen-aspects + scope-engine foundations. Full-fidelity replica of all four layers: trait composition (needs/neededBy), DOM traversal with attribute inheritance, CSS selector engine, and rule-based class content delivery. Also serves as a standalone demonstration template.

@sini
sini / 2026-05-22-nest-traits-schema-native-redesign.md
Created May 22, 2026 19:25
Nest traits schema-native redesign — replace __traitName conventions with gen-schema instances

Nest Traits Schema-Native Redesign

Date: 2026-05-22 Status: Design approved Location: scope-engine/templates/nest-traits/ Prerequisite: Builds on the existing nest-traits template (feat/nest-traits-template branch)

Goal

Replace the convention-based trait model (__traitName, magic key checks, raw attrsets) with gen-schema-native traits. Traits become instances of a trait kind in a gen-schema registry. The engine works with trait instances directly, never checking for magic keys on raw attrsets.