Skip to content

Phase Pipeline

Panix executes an ordered pipeline:

Inspect → Bootstrap → Build → Transfer → Secrets → Activate

flowchart LR
  subgraph Inspect
    direction TB

    A1[TCP reachability] --> B1[SSH echo OK]
    B1 --> C1[uname -m]
    C1 --> D1[id -u]
    D1 --> E1[cat /etc/os-release]
    E1 --> F1[nix-env --profile --list-generations]
  end

  subgraph Bootstrap
    direction TB

    A2[kexec] --> B2[encryption keys]
    B2 --> C2[disko]
    C2 --> D2[post-bootstrap hooks]
  end

  subgraph Per-installable
    subgraph Build
      A3[nix build --print-out-paths]
    end
  end

  subgraph Transfer
    A4[nix copy --to target]
  end

  subgraph Secrets
    A5[rsync or command stream]
  end

  subgraph Activate
    direction TB

    A6[nixos-install --system] --> B6[post install hooks]
    B6 --> C6[reboot]
    C6 --> D6[post bootstrap provisioned hooks]

    E6[nix-env --profile --set] --> F6[switch-to-configuration]
  end

  subgraph Rollback
    A7[readlink] --> B7[nix-env --profile --set]
    B7 --> C7[switch-to-configuration switch]
  end

  Start --> Inspect
  Start --> Build

  Inspect --> Bootstrap
  Bootstrap --> Build
  Build --> Done
  Build --> Transfer
  Transfer --> Secrets
  Secrets --> Activate
  Activate --> Done

  Inspect --> Build
  Build --> Secrets
  Build --> Activate
  Transfer --> Activate

  Inspect --> Rollback
  Rollback --> Done

  style Inspect fill:#cde8f5,stroke:#6272A4,stroke-width:2px,color:#333,fontWeight:bold
  style Bootstrap fill:#cde8f5,stroke:#6272A4,stroke-width:2px,color:#333,fontWeight:bold
  style Per-installable fill:#ffddaa,stroke:#d79b00,stroke-width:2px,color:#333,fontStyle:italic
  style Build fill:#cde8f5,stroke:#6272A4,stroke-width:2px,color:#333,fontWeight:bold
  style Transfer fill:#cde8f5,stroke:#6272A4,stroke-width:2px,color:#333,fontWeight:bold
  style Secrets fill:#cde8f5,stroke:#6272A4,stroke-width:2px,color:#333,fontWeight:bold
  style Activate fill:#cde8f5,stroke:#6272A4,stroke-width:2px,color:#333,fontWeight:bold
  style Rollback fill:#e5e6e8,stroke:#6B7280,stroke-width:2px,color:#333,fontWeight:bold

  style Start fill:#007da7,stroke:#007da7,color:#fff,fontWeight:bold
  style Done fill:#14532D,stroke:#14532D,color:#fff,fontWeight:bold

  linkStyle default stroke:#6272A4,stroke-width:1.5px
PhaseScopePurpose
InspectPer-machineTCP reachability, SSH authentication, architecture and kernel detection, OS detection, Nix availability, generation discovery
BootstrapPer-machinePer installable type: NixOS bootstrap (kexec into NixOS installer if needed, encryption keys transfer if provided, disko partitioning) or Nix installer bootstrap (install Nix on targets that lack it); see the Bootstrap guide
BuildPer-installableBuild the installable closure via nix build (local or remote mode)
TransferPer-machinenix copy closure to target
SecretsPer-machineTransfer local_path files/directories via rsync, or stream command stdout to the remote path, with proper ownership
ActivatePer-machineDispatches based on installable type: switch-to-configuration (nixos), activate (darwin/home/droid), or nix profile add for packages (nix profile install when Lix is detected)
PhaseScopePurpose
RollbackPer-machineSwitch to a previous generation via the type’s activation mechanism, for any type with a profile path

Rollback also runs automatically during Activate when activation fails and the machine has auto_rollback: true: see Auto Rollback.

The Build phase runs once per installable, not per machine: three machines sharing an installable build once (see the configuration model). The closure is then transferred to each machine independently, in parallel.

The TUI shows this unfolding in real time:

Phase status

When a phase fails, inspect the logs and retry just the failed phases without restarting the workflow: see TUI keybinds.