Skip to content

feat(engine): Engine::bootstrap wires LiveNixInstaller + writes /etc/nix/nix.conf#56

Merged
UnbreakableMJ merged 1 commit into
mainfrom
feat/engine-bootstrap
Apr 28, 2026
Merged

feat(engine): Engine::bootstrap wires LiveNixInstaller + writes /etc/nix/nix.conf#56
UnbreakableMJ merged 1 commit into
mainfrom
feat/engine-bootstrap

Conversation

@UnbreakableMJ

Copy link
Copy Markdown
Contributor

Summary

Implements the engine half of ADR-0012 (pearlite bootstrap) and ADR-0013 (system-wide nix.conf). The CLI surface — pearlite bootstrap subcommand + installer-script-fetch path — lands in the next chunk; this PR is the engine method the subcommand will dispatch to.

  • New crates/pearlite-engine/src/bootstrap.rs:
    • BootstrapOutcome { install: InstallOutcome, nix_conf_written: bool }.
    • Engine::bootstrap(host_file, installer, script_path, nix_conf_path) loads the host via the existing Nickel adapter, requires a declared [nix.installer] block, calls installer.install_if_missing with the operator-supplied SHA pin, then writes /etc/nix/nix.conf idempotently with experimental-features = nix-command flakes per ADR-0013.
  • BootstrapError enum in errors.rs: Nickel / NixNotDeclared / Installer / Fs / Io variants with From impls.
  • Engine::nickel() accessor (pub(crate)) so bootstrap.rs can reuse the same evaluator.
  • nix moved from dev-dep to regular dep so we can resolve current uid/gid for the temp-dir-injected nix.conf write in tests; production uses the same pearlite-fs::write_etc_atomic pipeline as ConfigWrite.

Five new tests with MockNixInstaller covering: declared-SHA pass-through, fresh nix.conf write, idempotent skip when the experimental-features line is already present (operator preamble preserved), NixNotDeclared error, and the already-installed short-circuit.

Bootstrap intentionally does not run schema validation — that's plan's job; bootstrap is a one-shot side-effect with its own narrower precondition (NixNotDeclared).

Test plan

  • cargo test --workspace --all-features — 312 passing (+5 new)
  • cargo clippy --workspace --all-targets --all-features -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • scripts/ci/check-spdx.sh — clean
  • pearlite-audit check . — 1 check, 0 violations
  • CI green on T1 / T2 / T3

🤖 Generated with Claude Code

…nix/nix.conf

Implements ADR-0012 + ADR-0013 on the engine side. The CLI surface
(`pearlite bootstrap` subcommand + script-fetch path) lands in the
next chunk; this PR wires the engine method that subcommand will
dispatch to.

- New `crates/pearlite-engine/src/bootstrap.rs`:
  - `BootstrapOutcome { install: InstallOutcome, nix_conf_written: bool }`.
  - `Engine::bootstrap(host_file, installer, script_path, nix_conf_path)`
    loads the host via the existing Nickel adapter, requires a
    declared `[nix.installer]` block, calls `installer.install_if_missing`
    with the operator-supplied SHA pin, then writes
    `/etc/nix/nix.conf` idempotently per ADR-0013.
- `BootstrapError` enum in `errors.rs`: Nickel / NixNotDeclared /
  Installer / Fs / Io variants. `From` impls for the wrapped errors.
- `Engine::nickel()` accessor (pub(crate)) so bootstrap.rs can
  reuse the same evaluator without duplicating the field.
- nix moved from dev-dep to regular dep so we can resolve current
  uid/gid for the temp-dir-injected nix.conf write in tests; the
  production write uses the same pearlite-fs::write_etc_atomic
  pipeline as ConfigWrite, no new I/O surface.
- Five tests with MockNixInstaller covering: declared-SHA pass-through,
  fresh nix.conf write, idempotent skip when line already present,
  NixNotDeclared error, and short-circuit when nix is already
  installed.

Tests: 312 passing (+5). Clippy clean. fmt clean. audit clean.
Bootstrap intentionally does not run schema validation — that's
plan's job; bootstrap is a one-shot side-effect with its own narrower
precondition.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@UnbreakableMJ
UnbreakableMJ merged commit a94e552 into main Apr 28, 2026
3 checks passed
@UnbreakableMJ
UnbreakableMJ deleted the feat/engine-bootstrap branch April 28, 2026 22:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant