feat(distro): compile Prolog facts to Nix and Guix without an LLM #3

Closed
nsaspy wants to merge 25 commits from feat/prolog-distro-nix-guix into bootstrap/ai-native-workstation
Owner

Goal

Make Symac's distribution layer symbolic and deterministic:

data-only Prolog facts
  -> schema gate
  -> Prolog expert derivation
  -> portable distro IR
  -> Nix or Guix renderer

No LLM is required to select a backend, derive packages, render configuration, enforce secret policy, or reject invalid state.

What landed

  • data-only fact reader: rules/directives/variables/unknown predicates fail closed
  • backend-neutral facts for hosts, roles, packages, services, features, environment, requirements and preferences
  • deterministic backend selection for auto
  • role and feature -> package derivation
  • backend package mappings with fact-driven overrides
  • typed distro_ir/8
  • NixOS module renderer
  • Guix Scheme definitions renderer
  • secret-source facts restricted to environment / wallet / auth-source; secret values are rejected
  • symac-distro check|plan|render CLI
  • example workstation fact graph
  • Nix flake package/app/check for the compiler itself
  • generated Nix is parsed by Nix; generated Guile is reader-validated
  • SWI-Prolog regression suite and CI wiring
  • architecture/usage documentation

Examples

nix run .#symac-distro -- render nix examples/distro/workstation.pl workstation
nix run .#symac-distro -- render guix examples/distro/workstation.pl workstation

Safety / determinism

Config fact files are parsed as terms and validated against a schema; they are not consulted as executable Prolog programs. Sensitive environment-variable names cannot be assigned values through session_variable/3. Only source metadata may be stored via secret_source/3.

Stack

This PR intentionally targets bootstrap/ai-native-workstation (PR #1) so the distro/compiler slice stays separate from the architecture bootstrap.

## Goal Make Symac's distribution layer symbolic and deterministic: ``` data-only Prolog facts -> schema gate -> Prolog expert derivation -> portable distro IR -> Nix or Guix renderer ``` No LLM is required to select a backend, derive packages, render configuration, enforce secret policy, or reject invalid state. ## What landed - data-only fact reader: rules/directives/variables/unknown predicates fail closed - backend-neutral facts for hosts, roles, packages, services, features, environment, requirements and preferences - deterministic backend selection for `auto` - role and feature -> package derivation - backend package mappings with fact-driven overrides - typed `distro_ir/8` - NixOS module renderer - Guix Scheme definitions renderer - secret-source facts restricted to environment / wallet / auth-source; secret values are rejected - `symac-distro check|plan|render` CLI - example workstation fact graph - Nix flake package/app/check for the compiler itself - generated Nix is parsed by Nix; generated Guile is reader-validated - SWI-Prolog regression suite and CI wiring - architecture/usage documentation ## Examples ```sh nix run .#symac-distro -- render nix examples/distro/workstation.pl workstation nix run .#symac-distro -- render guix examples/distro/workstation.pl workstation ``` ## Safety / determinism Config fact files are parsed as terms and validated against a schema; they are not consulted as executable Prolog programs. Sensitive environment-variable names cannot be assigned values through `session_variable/3`. Only source metadata may be stored via `secret_source/3`. ## Stack This PR intentionally targets `bootstrap/ai-native-workstation` (PR #1) so the distro/compiler slice stays separate from the architecture bootstrap.
ci(distro): parse generated Nix outside sandbox
Some checks failed
CI / common-lisp (push) Failing after 15s
CI / common-lisp (pull_request) Failing after 37s
6f43ff93bf
nsaspy closed this pull request 2026-09-21 19:45:14 +00:00
Some checks failed
CI / common-lisp (push) Failing after 15s
CI / common-lisp (pull_request) Failing after 37s

Pull request closed

Sign in to join this conversation.
No description provided.