diff --git a/Notes.txt b/Notes.txt
index 8ff8754a796d73ef5fc1b2413c0466e0b9f08bb2..97908c5992a34eecaeedbb828689cfc05aecf6d2 100644
--- a/Notes.txt
+++ b/Notes.txt
@@ -148,3 +148,16 @@
   * Nix helps you make the same piece of software more than once.
   * What's so hard about that?
   * Software is fantastically complex
+
+
+* Put all the code snippets into a gist
+* replace almonds with xaos
+* put example of running something you installed with `nix shell`
+* explain `nix shell` more
+* explain flakes
+* explain language control flow
+* may-lee
+  * how to see what packages are installed in a `nix shell`
+  * when installing to a profile?
+
+* Link to slide repo on last slide
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000000000000000000000000000000000000..d517ccddda2ea5bf32caebfdd7f44c81183b133a
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,10 @@
+Nix
+===
+
+This project contains a slide deck and notes for an introductory-level Nix presentation.
+
+To build the slide deck, use nix::
+
+  nix build
+
+The result will be at `result/nixos-part1-slides.html`.
diff --git a/default.nix b/default.nix
index edb6724370215809be0f18e0df32f55500af019b..c3688090301b7443e9c926d7afcd5ff51af8a591 100644
--- a/default.nix
+++ b/default.nix
@@ -18,7 +18,8 @@ pkgs.stdenv.mkDerivation rec {
         --resource-path $src \
         --standalone \
         --self-contained \
-        --variable revealjs-url:file://${sources."reveal.js"} \
+        --variable=revealjs-url:file://${sources."reveal.js"} \
+        --variable=slideNumber:1 \
         -t revealjs \
         -o "$outpath" \
         "$inpath"
diff --git a/references b/references
new file mode 100644
index 0000000000000000000000000000000000000000..7bf5ac1b0cf88cf63dbc605217785198572abcaf
--- /dev/null
+++ b/references
@@ -0,0 +1,5 @@
+* These slides
+
+  git clone https://whetstone.private.storage/jcalderone/nix-training-material.git
+  cd nix-training-material
+  nix build
diff --git a/shell.nix b/shell.nix
index b5d1f87e5512c3bf8ab5a1fdfff84aff82d086d6..e1d6b5e44512d3402b0145ed4f934d8fb2093f74 100644
--- a/shell.nix
+++ b/shell.nix
@@ -17,6 +17,10 @@ pkgs.mkShell {
     qemu-img create -f qcow2 nixstore.qcow 50G;
   '';
 
+  boot-installer = ''
+    qemu-system-x86_64 -m 2048m -enable-kvm -cdrom ${ubuntu-mini-iso} -drive file=root.qcow,if=none,format=qcow2,id=root -drive file=nixstore.qcow,if=none,format=qcow2,id=store -device virtio-blk-pci,drive=root,bootindex=1 -device virtio-blk-pci,drive=store,bootindex=2 -nic user,id=eth0,hostfwd=tcp:127.0.0.1:2222-:22
+  '';
+
   boot = ''
     qemu-system-x86_64 -m 2048m -enable-kvm -cdrom ${ubuntu-mini-iso} -drive file=root.qcow,if=none,format=qcow2,id=root -drive file=nixstore.qcow,if=none,format=qcow2,id=store -device virtio-blk-pci,drive=root,bootindex=1 -device virtio-blk-pci,drive=store,bootindex=2 -nic user,id=eth0,hostfwd=tcp:127.0.0.1:2222-:22
   '';
diff --git a/src/hands-on-notes b/src/hands-on-notes
new file mode 100644
index 0000000000000000000000000000000000000000..24a88cfa1cc5472cbeab0155f566fdff00207517
--- /dev/null
+++ b/src/hands-on-notes
@@ -0,0 +1,186 @@
+# nix search
+
+```sh
+$ nix search nixpkgs almonds
+* legacyPackages.x86_64-linux.almonds (3.6)
+  Fractal viewer
+```
+
+::: notes
+
+* `nix search` searches nixpkgs, the package tree, and shows matches
+* there are a lot of packages, try searching for something
+* mention xaos is prettier
+
+:::
+
+# nix profile install
+
+```sh
+$ nix profile install nixpkgs#almonds
+```
+
+::: notes
+
+* Once you find a package one thing you can do is install it
+* `nix profile` imperatively manages a "profile"
+* a profile is a self-containing set of installed software
+* each user has their own profile
+* you can install software into the profile
+* only when the profile is active is the software available
+
+:::
+
+# nix profile list
+
+```sh
+$ nix profile list
+ flake:nixpkgs#legacyPackages.x86_64-linux.almonds github:NixOS/nixpkgs/...
+```
+
+::: notes
+
+* show what's installed in the profile
+* the output is ... verbose
+* but it shows you exactly what version of the package you have installed
+
+:::
+
+# nix profile remove
+
+```sh
+$ nix profile remove legacyPackages.x86_64-linux.almonds
+$ nix profile list
+$
+```
+
+::: notes
+
+* you can uninstall them too
+* so far this is pretty normal stuff
+* most package managers can do all this
+  though fewer can do per-user installs
+
+:::
+
+# nix profile history
+
+```sh
+$ nix profile history
+Version 6 (2022-03-01) <- 5:
+  flake:nixpkgs#legacyPackages.x86_64-linux.almonds: ∅ -> 3.6
+
+Version 7 (2022-03-01) <- 6:
+  flake:nixpkgs#legacyPackages.x86_64-linux.almonds: 3.6 -> ∅
+```
+
+::: notes
+
+* Here's a neat trick.
+* Since profiles are self-contained it is easy to keep old version
+* You can see previous versions of the profile
+* You can see what changed between them
+
+:::
+
+# flakes / nix registry list
+
+::: notes
+
+* Maybe you noticed the word "flake" in the nix profile output
+* I don't think we'll have time to explore flakes in depth today
+* For now, if you think of a "flake" as a package tree (and nixpkgs as just one of many possible package trees) the rest should make sense
+
+:::
+
+# nix profile rollback
+
+```sh
+$ nix profile rollback --to 6
+switching profile from version 7 to 6
+```
+
+::: notes
+
+* And you can switch back to them.
+* rollback is not limited to going backwards
+* the expected use-case is that you break your environment somehow and want to get back to a working version
+
+:::
+
+# nix shell
+
+```sh
+nix shell nixpkgs#almonds
+```
+
+::: notes
+
+* `nix shell` starts a new shell running a new disposable profile
+* the new profile has the request packages installed in it
+* exit the shell, the profile is forgotten, the packages are unavailable
+
+:::
+
+# shell.nix
+
+`shell.nix`
+```nix
+let pkgs = import <nixpkgs> {};
+in pkgs.stdenv.mkDerivation {
+  name = "shell-demo";
+  shellHook = ''
+  echo "Hello world"
+  '';
+}
+```
+
+# How does Nix work?
+### Derivations
+
+```nix
+builtins.derivation {
+  name = "example-derivation";
+  builder = builtins.toFile "builder.sh" "echo 'Hello, world'"
+  system = "x86_64-linux";
+}
+```
+
+::: notes
+:::
+
+# How does Nix work?
+
+```include
+{ stdenv }:
+stdenv.mkDerivation {
+  name = "demo-derivation";
+  src = ./demo;
+  phases = [ "installPhase" ];
+
+  installPhase = ''
+    mkdir $out
+	echo "Hello, world" > $out/greeting.txt
+  '';
+}
+```
+
+# Q & A
+
+* If you want more, let me know on Slack.
+*
+
+# Installing NixOS on Debian
+
+```sh
+$ sh <(curl -L https://nixos.org/nix/install) --daemon
+[ a ton of output ]
+```
+
+
+::: notes
+
+* `$ $boot`
+* training / password
+
+:::
diff --git a/src/nixos-part1-slides.md b/src/nixos-part1-slides.md
index 4af9be505cee96987916c6c66177382170a2900b..e03d99c0f9b445fbd69fe5a3cac5715cec94d814 100644
--- a/src/nixos-part1-slides.md
+++ b/src/nixos-part1-slides.md
@@ -1,11 +1,15 @@
----
-author: Jean-Paul Calderone
-title: Nix
-subtitle: Make Software Suck Less
-date: 2022-03-03
----
+#
+
+<div style="width: 100%">
+<div style="align: center">Nix</div>
+<div style="align: center; font-size: 70%">Make Software Suck Less</div>
+
+<div style="font-size: 60%">
+<span style="float: left">Jean-Paul Calderone</span>
+<span style="float: right">2022-03-03</span>
+</div>
 
-# Welcome
+</div>
 
 ::: notes
 
@@ -19,33 +23,37 @@ date: 2022-03-03
 :::
 
 #
-## Why Nix?
+## What is Nix for?
 ## What tools are provided?
 ## Install some stuff!
 ## How does it work?
-## Make your own!
+## Q & A
 
 ::: notes
 
-Here's an overview of what we'll cover today.
+* Here's an overview of what we'll cover today.
+* I'll explain what it is and why that's interesting
+* We'll look at the tools that it provides
+* Then we'll do some hands-on activities using those tools
+* Then if we have time we'll look behind the scenes a little to see how it works.
 
 :::
 
-# Why Nix?
+# What is Nix for?
 
 ## Reproducible Builds
 
 ::: notes
 
-* So, why?
-* The reason I'll focus on today is reproducible builds.
+* It /can/ be useful for a lot of different things.
+* The unifying theme that I'm going to focus on today is its use in reproducible builds.
 
 :::
 
 #
 ###
 
-Reproducible *Builds*
+*Builds*, Reproducible
 
 ```python
 def b2a(os):
@@ -78,16 +86,18 @@ Nix helps you *build software*.
 #
 ###
 
-*Reproducible* Builds
+Builds, *Reproducible*
 
 ::: notes
 
-* Once you have something hardware can execute,
+* So what's the "reproducible" part?
+* Well...
+* After you build the software
   you might have some hardware execute it.
 * If your plan was good *and the build was correct* then the results might be useful.
-* If your plan was good the build was *incorrect* then the results be less useful.
+* If your plan was good and the build was *incorrect* then the results might be less useful.
 * If the build is different each time then it's hard to know if the results will be useful or not.
-* What's the big deal?
+* Why would the build be different each time?
 * Aren't computers good at doing the same thing over and over?
 
 :::
@@ -165,17 +175,35 @@ wormhole receive 3-eskimo-topmost
 #
 ###
 
-![](qmarks.webp)
+Does the plan specify the version of ...
+
+* the compiler, assembler, linker
+* statically linked libraries
+* the C library and other dynamically linked libraries
+* the runtime linker itself
+* the content of runtime configuration files
 
 ::: notes
 
 * Since the plan is so complex, we leave parts of it out.
-* We often leave out details about ...
-* versions of build-time tools (eg the C compiler)
-* versions of runtime dependencies (eg libc)
-* exact configurations for all those dependencies
+* Here are some examples of pieces we often leave out of build plans
+* Some of these are traditionally considered "build" dependencies and others "runtime" dependencies
+* But that's kind of an arbitrary distinction
+* They all influence what software is actually executed
+* Variations in any of them lead to...
+* variations in the software that is built leading to...
+* variations in the ultimate execution result.
+
+:::
+
+#
+
+![](qmarks.webp)
 
-* These pieces get satisfied by whatever happens to be in the build environment
+::: notes
+
+* Of course the plan cannot be executed with missing pieces
+* These pieces get satisfied by whatever happens to be in the environment
 * The consequence is each build has the opportunity to follow a completely unique plan -
   and produce a completely unique piece of software.
 
@@ -201,28 +229,69 @@ Nix builds are *the same every time*.
 
 ::: notes
 
+* Nix provides tools to make it easier to specify all of the pieces.
+* and Nix requires all of the pieces be specified.
+
 :::
 
-# What tools does Nix provide?
+# What tools are provided?
 
 * NixOS
 * Nixpkgs
 * nix command line interface
 * the Nix language
 
+::: notes
+
+* So let's talk about those tools.
+* They can be grouped into roughly four areas
+* Let's look at them one by one
+
+:::
+
 #
 ### NixOS the Linux distro
 
-* An OS install is the combination of:
-  * software packages and
-  * their configuration
-* NixOS takes software packages from Nixpkgs and adds configuration.
+A complete NixOS "plan".
+
+<div style="font-size: 90%; width: 150%">
+```nix
+let
+  src = builtins.fetchTarball {
+    name = "nixpkgs";
+	url = "https://t.ly/MxPy";
+	sha256 = "162dywda2dvfj1248afxc45kcrg83appjd0nmdb541hl7rnncf02";
+  };
+  pkgs = import src { };
+in {
+  imports                     = [
+    <nixpkgs/nixos/modules/virtualisation/amazon-image.nix>
+  ];
+  ec2.hvm                     = true;
+  boot.kernel.sysctl          = { "vm.swappiness" = 0; };
+  environments.systemPackages = [ pkgs.git ];
+}
+```
+</div>
 
 ::: notes
 
-* What if your entire OS install were a reproducible build?
+* What if your entire OS were the result of a reproducible build?
 * That's NixOS
-* NixOS adds a reproducible configuration layer on top of packages from Nixpkgs.
+* NixOS takes reproducible packages from nixpkgs
+* and adds a reproducible configuration layer on top
+
+* This is a complete (if spartan) NixOS configuration
+* It demonstrates supplying some configuration to the kernel
+* And installing the git package system-wide
+* This expression /fully/ and /reproducibly/ describes a NixOS installation
+
+* I don't expect the details of this slide to make sense right now
+* Just consider -
+* this is a lot of text for a slide but
+* it's hardly any text at all for a complete Linux system definition.
+
+* Let's move on from NixOS for the moment
 
 :::
 
@@ -244,18 +313,36 @@ Nix builds are *the same every time*.
 :::
 
 #
-### Nix the command line tool
+### Nix the expression language
 
-* `nix-build`
-* `nix-shell`
-* `nix repl`
-* (and others)
+<div style="font-size: 90%; width: 150%">
+```nix
+let
+  src = builtins.fetchTarball {
+    name = "nixpkgs";
+	url = "https://t.ly/MxPy";
+	sha256 = "162dywda2dvfj1248afxc45kcrg83appjd0nmdb541hl7rnncf02";
+  };
+  pkgs = import src { };
+in {
+  imports                     = [
+    <nixpkgs/nixos/modules/virtualisation/amazon-image.nix>
+  ];
+  ec2.hvm                     = true;
+  boot.kernel.sysctl          = { "vm.swappiness" = 0; };
+  environments.systemPackages = [ pkgs.git ];
+}
+```
+</div>
 
 ::: notes
 
-* There are a lot of tools to use and interact with Nix.
-* Many of them interpret expressions in the Nix language.
-* We'll use some in a minute.
+* Here's that configuration again.
+* This is written in Nix the language.
+* This is a declarative, functional expression language.
+* It's also pretty basic as such things go and could probably didn't need to be invented
+* It's not strictly necessary for all uses of Nix but in some cases you do need to read or write it.
+* So let's take a closer look!
 
 :::
 
@@ -263,156 +350,107 @@ Nix builds are *the same every time*.
 ### Nix the expression language
 
 ```nix
-nix-repl> 0
+# A comment
+
+# An integer
 0
 
-nix-repl> "Hello, world."
-"Hello, world."
+# A floating point
+0.5
 
-nix-repl> [ 1 2 3 ]
-[ 1 2 3 ]
+# A text (mostly) string
+"Hello, world."
 
-nix-repl> { a = "b"; }
-{ a = "b"; }
+# A list of all of the above
+[ 1 1.5 "2" ]
 ```
 
 ::: notes
 
-* It's an expression language.
 * Everything is an expression.
-* An expression either is or evaluates to a simple value.
+* An expression either is or evaluates to a value.
+* Values are immutable.
 * Here's integers, strings, lists, "attribute sets"
+* This output is from `nix repl`
+* If you have nix installed, go ahead and try it out
 
 :::
 
 #
 ### Nix the expression language
 
-```nix
-nix-repl>
-  let
-    add = x: y: x + y;
-  in
-    add 1 2
-3
-```
 
-::: notes
-
-* It's a functional language.
-* (note, reformatted for readability)
-
-:::
-
-#
-### Nix the expression language
 
 ```nix
-nix-repl>
-  let
-    add = x: y: x + y;
-	add-one = add 1;
-  in
-    add-one 2
-3
-```
-
-::: notes
-
-* It has partial application.
-* It has functions and you can treat them as values.
-* (note, reformatted for readability)
-
-:::
-
-# Hands-On
-## nix-env
-
-```sh
-nix search xaos
-nix-env --install --attr nixos.xaos
+# An attribute sets (attrsets)
+{ a = "b"; }
 
-nix-env --query
+# A "recursive" attrset
+rec { a = "b"; c = a; }
 
-nix-env --uninstall xaos
+# nesting notation
+{ a.b = "c"; }
 
-nix-env --list-generations
-nix-env --rollback
+# equivalent to
+{ a = { b = "c"; }; }
 ```
 
 ::: notes
 
-* I assume you already have the Nix tools installed.
-* `nix search` searches the package tree
-* `nix-env` imperatively manages a "profile"
-* you can install software into the profile
-* uninstall
-* query (ie, list what it contains)
-* generations of a profile are automatically kept around
-* list them, delete them, switch between them
+* There is also a key/value mapping type.
+* The keys are identifier, the values are arbitrary.
+* There's support for self-referential sets
+* And syntax to make nested sets more convenient
+* Nix uses attrsets a lot.
 
 :::
 
-# Hands-On
-## nix-shell
+#
+### Nix the expression language
 
-```sh
-nix-shell -p xaos
+```nix
+let
+  add-one = x: x + 1;
+in
+  add-one 2
 ```
 
 ::: notes
 
-* `nix-shell` starts a new shell that has the requested packages installed
-* exit the shell, the packages are gone
+* I mentioned it's a functional language.
+* Functions are treated values
+* Here's a function definition and application
+* This also demonstrates the let/in expression
+* The let/in expression binds the name "add dash one" to a function
+* Then evaluates that function with an argument of 2
+* The result, of course, is 3
 
-:::
+* This isn't the whole language of course but there are probably better ways
+  to learn the rest than from a slideshow.
 
-# Hands-On
-## nix-shell
-
-`shell.nix`
-```nix
-let pkgs = import <nixpkgs> {};
-in pkgs.stdenv.mkDerivation {
-  name = "shell-demo";
-  shellHook = ''
-  echo "Hello world"
-  '';
-}
-```
-
-::: notes
-
-*
+* Let's move on to the hands-on activity.
 
 :::
 
-# How does Nix work?
-### Derivations
+#
+### Nix the command line tool
 
-```nix
-builtins.derivation {
-  name = "example-derivation";
-  builder = builtins.toFile "builder.sh" "echo 'Hello, world'"
-  system = "x86_64-linux";
-}
-```
+* `nix search`
+* `nix profile`
+* `nix shell`
+* `nix repl`
+* `nix build`
+* (and others)
 
 ::: notes
-:::
 
-# How does Nix work?
+* There are a lot of tools to use and interact with Nix.
+* Many of them interpret expressions in the Nix language.
+* Let's try using some
 
-```include
-{ stdenv }:
-stdenv.mkDerivation {
-  name = "demo-derivation";
-  src = ./demo;
-  phases = [ "installPhase" ];
+* STOP RECORDING
+* STOP SCREEN SHARING
+* SWITCH TO TRAINING VM
+* START SCREEN SHARING
 
-  installPhase = ''
-    mkdir $out
-	echo "Hello, world" > $out/greeting.txt
-  '';
-}
-```
+:::