An easy-to-host PDS on the ATProtocol, MacOS. Grandma-approved.

feat(MM-66): add Docker image derived from Nix build #4

Summary#

  • Adds nix/docker.nix — a standalone buildLayeredImage derivation for the relay binary, including sqlite runtime, CA certificates, and timezone data
  • Extends flake.nix to expose packages.{aarch64,x86_64}-linux.docker-image using pkgs.lib.optionalAttrs pkgs.stdenv.isLinux; the Darwin package outputs are unchanged
  • Updates CLAUDE.md with the nix build .#docker-image command (Linux-only caveat) and documents the new nix/ directory in the project structure
  • Adds tests/verify-mm66.sh — automated verification script for AC1.3 (docker-image absent on Darwin) and AC3.4 (nix/docker.nix tracked by git)

Test Plan#

  • nix eval confirms docker-image present for aarch64-linux and x86_64-linux
  • nix eval confirms docker-image absent for aarch64-darwin and x86_64-darwin (AC1.3)
  • git ls-files nix/docker.nix returns the file (AC3.4)
  • bash tests/verify-mm66.sh passes
  • Linux verification required: see docs/test-plans/2026-03-08-MM-66.md for the full human test plan (AC2.1–AC5.1 require a Linux system with Docker)
Labels

None yet.

assignee

None yet.

Participants 1
AT URI
at://did:web:malpercio.dev/sh.tangled.repo.pull/3mgl4gjdehj22
+490
Interdiff #0 #1
CLAUDE.md

This file has not been changed.

docs/design-plans/2026-03-08-MM-66.md

This file has not been changed.

docs/test-plans/2026-03-08-MM-66.md

This file has not been changed.

flake.nix

This file has not been changed.

nix/docker.nix

This file has not been changed.

tests/verify-mm66.sh

This file has not been changed.

+1
.gitignore
··· 20 .devenv/ 21 .direnv/ 22 devenv.local.nix
··· 20 .devenv/ 21 .direnv/ 22 devenv.local.nix 23 + /result
+176
docs/implementation-plans/2026-03-08-MM-66/phase_01.md
···
··· 1 + # MM-66 Docker Image Implementation Plan — Phase 1 2 + 3 + **Goal:** Create `nix/docker.nix` and extend `flake.nix` so `docker-image` is exposed as a flake package on Linux targets only. 4 + 5 + **Architecture:** A new file `nix/docker.nix` holds the `buildLayeredImage` derivation as a standalone Nix function `{ pkgs, relay }:`. `flake.nix` merges this into the existing `forEachSystem` lambda return value using `pkgs.lib.optionalAttrs pkgs.stdenv.isLinux { ... }`, which evaluates to `{}` on Darwin and `{ docker-image = ...; }` on Linux — making the conditional a zero-cost no-op on macOS. 6 + 7 + **Tech Stack:** Nix flakes, nixpkgs `dockerTools.buildLayeredImage`, crane (relay binary already built by MM-65) 8 + 9 + **Scope:** Phase 1 of 2 from the original design. Phase 2 covers build verification and CLAUDE.md update. 10 + 11 + **Codebase verified:** 2026-03-08 12 + 13 + --- 14 + 15 + ## Acceptance Criteria Coverage 16 + 17 + This phase implements: 18 + 19 + ### MM-66.AC1: docker-image outputs exist in the flake 20 + - **MM-66.AC1.1 Success:** `nix flake show --accept-flake-config` (on Linux) lists `packages.x86_64-linux.docker-image` 21 + - **MM-66.AC1.2 Success:** `nix flake show --accept-flake-config` (on Linux) lists `packages.aarch64-linux.docker-image` 22 + - **MM-66.AC1.3 Negative:** `packages.aarch64-darwin.docker-image` and `packages.x86_64-darwin.docker-image` are not present in `nix flake show` output 23 + 24 + ### MM-66.AC3: Image contents 25 + - **MM-66.AC3.4 Success:** `nix/docker.nix` exists and is tracked by git (`git ls-files nix/docker.nix` returns it) 26 + 27 + > **Note on AC1.1 / AC1.2:** These require a Linux system to verify. On macOS, `nix flake show` will not list `docker-image` (AC1.3 is verifiable now; AC1.1 and AC1.2 are verified in Phase 2 on a Linux system or CI). 28 + 29 + --- 30 + 31 + <!-- START_SUBCOMPONENT_A (tasks 1-3) --> 32 + 33 + <!-- START_TASK_1 --> 34 + ### Task 1: Create `nix/docker.nix` 35 + 36 + **Files:** 37 + - Create: `nix/docker.nix` 38 + 39 + **Step 1: Create the `nix/` directory and write the derivation** 40 + 41 + ```bash 42 + mkdir nix 43 + ``` 44 + 45 + Then create `nix/docker.nix` with exactly this content: 46 + 47 + ```nix 48 + { pkgs, relay }: 49 + pkgs.dockerTools.buildLayeredImage { 50 + name = "relay"; 51 + tag = "latest"; 52 + contents = [ relay pkgs.sqlite.out pkgs.cacert pkgs.tzdata ]; 53 + config = { 54 + Entrypoint = [ "${relay}/bin/relay" ]; 55 + Env = [ 56 + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" 57 + "TZDIR=${pkgs.tzdata}/share/zoneinfo" 58 + ]; 59 + }; 60 + } 61 + ``` 62 + 63 + **Explanation of each field:** 64 + - `name = "relay"`: The Docker image name that appears in `docker images`. 65 + - `tag = "latest"`: Placeholder tag; can be wired to `self.shortRev` later. 66 + - `contents`: List of derivations whose closure becomes the image filesystem. `pkgs.sqlite.out` is the runtime-library output of sqlite (carries `libsqlite3.so`); `.dev` (headers) is omitted. 67 + - `Entrypoint`: Uses Nix string interpolation — `${relay}` expands to the relay's `/nix/store/...` path at evaluation time, so the entrypoint is always tied to the exact derivation. 68 + - `SSL_CERT_FILE` / `TZDIR`: Point into the Nix store paths of `cacert` and `tzdata` so TLS and timezone lookups work inside the container. 69 + 70 + **Step 2: No operational verification yet** — verification happens after flake.nix is updated in Task 2. 71 + 72 + <!-- END_TASK_1 --> 73 + 74 + <!-- START_TASK_2 --> 75 + ### Task 2: Extend `flake.nix` to expose `docker-image` on Linux 76 + 77 + **Files:** 78 + - Modify: `flake.nix:48-51` 79 + 80 + **Current content at lines 48–51:** 81 + 82 + ```nix 83 + in { 84 + inherit relay; 85 + default = relay; 86 + } 87 + ``` 88 + 89 + **Replace with:** 90 + 91 + ```nix 92 + in { 93 + inherit relay; 94 + default = relay; 95 + } // pkgs.lib.optionalAttrs pkgs.stdenv.isLinux { 96 + docker-image = import ./nix/docker.nix { inherit pkgs relay; }; 97 + } 98 + ``` 99 + 100 + **Why `pkgs.lib.optionalAttrs`:** Returns the attribute set when the condition is true, and `{}` otherwise. On Darwin, the merge is `{ inherit relay; default = relay; } // {} = { inherit relay; default = relay; }`. On Linux, the `docker-image` attribute is added. This keeps Darwin package outputs unchanged while adding the Linux-only output. 101 + 102 + **Why `import ./nix/docker.nix { inherit pkgs relay; }`:** Calls the function in `nix/docker.nix` with the current `pkgs` (for the target system) and the crane-built `relay` derivation. This is the standard nixpkgs package-expression calling convention. 103 + 104 + **Step 2: Verify the flake evaluates (catches Nix syntax errors)** 105 + 106 + ```bash 107 + nix flake show --accept-flake-config 108 + ``` 109 + 110 + Expected on macOS (aarch64-darwin): Output shows `packages.aarch64-darwin` with `relay` and `default`, but **no** `docker-image`. This is correct — `pkgs.stdenv.isLinux` is `false` on Darwin. 111 + 112 + Example output (macOS): 113 + ``` 114 + git+file:///path/to/ezpds 115 + ├───devShells 116 + │ ├───aarch64-darwin 117 + │ │ └───default: development environment 'devenv-shell' 118 + │ ... 119 + └───packages 120 + ├───aarch64-darwin 121 + │ ├───default: package 'relay-0.1.0' 122 + │ └───relay: package 'relay-0.1.0' 123 + ├───aarch64-linux 124 + │ ├───default: package 'relay-0.1.0' 125 + │ ├───docker-image: package 'docker-image.tar.gz' 126 + │ └───relay: package 'relay-0.1.0' 127 + ... 128 + ``` 129 + 130 + If the command errors with a Nix eval error, fix it before proceeding to Task 3. 131 + 132 + <!-- END_TASK_2 --> 133 + 134 + <!-- START_TASK_3 --> 135 + ### Task 3: Track files in git and commit 136 + 137 + **Files:** 138 + - `nix/docker.nix` (new) 139 + - `flake.nix` (modified) 140 + 141 + **Step 1: Stage both files** 142 + 143 + ```bash 144 + git add nix/docker.nix flake.nix 145 + ``` 146 + 147 + **Step 2: Verify AC3.4 — `nix/docker.nix` is tracked by git** 148 + 149 + ```bash 150 + git ls-files nix/docker.nix 151 + ``` 152 + 153 + Expected output: 154 + ``` 155 + nix/docker.nix 156 + ``` 157 + 158 + If empty, the file is not staged/tracked. Re-run `git add nix/docker.nix`. 159 + 160 + **Step 3: Verify AC1.3 (negative) on macOS — `docker-image` is NOT present for Darwin** 161 + 162 + ```bash 163 + nix flake show --accept-flake-config 2>/dev/null | grep docker-image 164 + ``` 165 + 166 + Expected: Lines for `aarch64-linux` and `x86_64-linux` only. No `aarch64-darwin` or `x86_64-darwin` lines. If `docker-image` appears under a Darwin system, the `optionalAttrs` condition is wrong — re-check Task 2. 167 + 168 + **Step 4: Commit** 169 + 170 + ```bash 171 + git commit -m "feat(MM-66): add nix/docker.nix and expose docker-image on Linux" 172 + ``` 173 + 174 + <!-- END_TASK_3 --> 175 + 176 + <!-- END_SUBCOMPONENT_A -->
+230
docs/implementation-plans/2026-03-08-MM-66/phase_02.md
···
··· 1 + # MM-66 Docker Image Implementation Plan — Phase 2 2 + 3 + **Goal:** Update CLAUDE.md with the `docker-image` Linux-only caveat, then verify the image builds, loads, runs, and meets size constraints on a Linux system. 4 + 5 + **Architecture:** No new Nix code. This phase has one code change (CLAUDE.md), and the remaining work is operational verification that must be executed on an x86_64-linux or aarch64-linux system (or via CI). All acceptance criteria in this phase require a Linux Docker daemon. 6 + 7 + **Tech Stack:** Nix CLI, Docker CLI (Linux only) 8 + 9 + **Scope:** Phase 2 of 2. Phase 1 created `nix/docker.nix` and extended `flake.nix`. 10 + 11 + **Codebase verified:** 2026-03-08 12 + 13 + --- 14 + 15 + ## Acceptance Criteria Coverage 16 + 17 + This phase verifies: 18 + 19 + ### MM-66.AC2: Image builds and loads 20 + - **MM-66.AC2.1 Success:** `nix build .#docker-image --accept-flake-config` completes without error on x86_64-linux 21 + - **MM-66.AC2.2 Success:** `nix build .#packages.aarch64-linux.docker-image --accept-flake-config` completes without error on an aarch64-linux or x86_64-linux system 22 + - **MM-66.AC2.3 Success:** `docker load < result` completes without error 23 + - **MM-66.AC2.4 Success:** `docker images` shows `relay:latest` after loading 24 + 25 + ### MM-66.AC3: Image contents 26 + - **MM-66.AC3.1 Success:** `docker run --rm relay:latest` exits without a "no such file" or dynamic linker error (relay binary and libsqlite3.so are present) 27 + - **MM-66.AC3.2 Success:** `docker inspect relay:latest` shows `SSL_CERT_FILE` env var pointing to a cacert store path 28 + - **MM-66.AC3.3 Success:** `docker inspect relay:latest` shows `TZDIR` env var pointing to a tzdata store path 29 + 30 + ### MM-66.AC4: Image size 31 + - **MM-66.AC4.1 Success:** `docker images relay` shows image size under 50 MB 32 + 33 + ### MM-66.AC5: Scope boundaries 34 + - **MM-66.AC5.1 Negative:** `docker run relay:latest` does not require a running HTTP server to start (relay is a stub; no HTTP health check in this ticket) 35 + 36 + --- 37 + 38 + > **All verification in this phase requires a Linux system with Docker installed.** 39 + > On macOS, `docker-image` is not exposed (by design). Use a Linux CI runner or a remote Linux builder. 40 + 41 + --- 42 + 43 + <!-- START_SUBCOMPONENT_A (tasks 1-2) --> 44 + 45 + <!-- START_TASK_1 --> 46 + ### Task 1: Update CLAUDE.md with `docker-image` Linux-only note 47 + 48 + **Files:** 49 + - Modify: `CLAUDE.md:13` (after the `nix build .#relay` line) 50 + 51 + **Current content at line 13:** 52 + 53 + ``` 54 + - `nix build .#relay --accept-flake-config` - Build relay binary (output at ./result/bin/relay) 55 + ``` 56 + 57 + **Add the following line immediately after line 13:** 58 + 59 + ``` 60 + - `nix build .#docker-image --accept-flake-config` - Build Docker image tarball (Linux only; `docker-image` is not exposed on macOS — use a remote Linux builder or CI) 61 + ``` 62 + 63 + The full Commands section should read: 64 + 65 + ```markdown 66 + ## Commands 67 + - `nix develop --impure --accept-flake-config` - Enter dev shell (flags required; --impure for devenv CWD detection, --accept-flake-config activates the Cachix binary cache in nixConfig — without it, a cold build takes 20+ minutes) 68 + - `nix build .#relay --accept-flake-config` - Build relay binary (output at ./result/bin/relay) 69 + - `nix build .#docker-image --accept-flake-config` - Build Docker image tarball (Linux only; `docker-image` is not exposed on macOS — use a remote Linux builder or CI) 70 + - `cargo build` - Build all crates 71 + - `cargo test` - Run all tests 72 + - `cargo clippy` - Lint 73 + - `cargo fmt --check` - Check formatting 74 + ``` 75 + 76 + **Verification:** 77 + 78 + ```bash 79 + grep "docker-image" CLAUDE.md 80 + ``` 81 + 82 + Expected: One line mentioning `nix build .#docker-image` and noting it is Linux-only. 83 + 84 + **Commit:** 85 + 86 + ```bash 87 + git add CLAUDE.md 88 + git commit -m "docs(MM-66): note docker-image is Linux-only in CLAUDE.md" 89 + ``` 90 + 91 + <!-- END_TASK_1 --> 92 + 93 + <!-- START_TASK_2 --> 94 + ### Task 2: Verify image on Linux (human verification checklist) 95 + 96 + > **Run these steps on an x86_64-linux or aarch64-linux system with Docker installed.** 97 + > This task documents acceptance-criteria verification — it is not automated. 98 + 99 + --- 100 + 101 + **Step 1: Build x86_64-linux image (verifies MM-66.AC2.1)** 102 + 103 + ```bash 104 + nix build .#docker-image --accept-flake-config 105 + ``` 106 + 107 + Expected: Exits 0. A `result` symlink appears pointing to a `.tar.gz` in the Nix store. 108 + 109 + If it fails with an eval error, ensure Phase 1 commit is present and re-check `nix/docker.nix` and `flake.nix`. 110 + 111 + --- 112 + 113 + **Step 2: Build aarch64-linux image (verifies MM-66.AC2.2)** 114 + 115 + On an x86_64-linux host (cross-compilation): 116 + 117 + ```bash 118 + nix build .#packages.aarch64-linux.docker-image --accept-flake-config 119 + ``` 120 + 121 + Expected: Exits 0. A `result` symlink appears for the aarch64 image. 122 + 123 + > Cross-compilation for aarch64 requires binfmt\_misc QEMU support or a configured remote builder. If unavailable, skip this step and mark it verified via CI. 124 + 125 + --- 126 + 127 + **Step 3: Load image into Docker (verifies MM-66.AC2.3 and MM-66.AC2.4)** 128 + 129 + First rebuild the x86_64 image if `result` is from the aarch64 build: 130 + 131 + ```bash 132 + nix build .#docker-image --accept-flake-config 133 + ``` 134 + 135 + Then load: 136 + 137 + ```bash 138 + docker load < result 139 + ``` 140 + 141 + Expected output contains: 142 + ``` 143 + Loaded image: relay:latest 144 + ``` 145 + 146 + Verify the image appears: 147 + 148 + ```bash 149 + docker images relay 150 + ``` 151 + 152 + Expected: At least one row showing `relay` / `latest`. 153 + 154 + --- 155 + 156 + **Step 4: Run the relay stub (verifies MM-66.AC3.1 and MM-66.AC5.1)** 157 + 158 + ```bash 159 + docker run --rm relay:latest 160 + ``` 161 + 162 + Expected: The container exits. There must be **no** `no such file or directory` or `error while loading shared libraries: libsqlite3.so` error. 163 + 164 + The relay is currently a stub and may exit with a non-zero code — that is acceptable. The absence of linker errors confirms `relay` binary and `libsqlite3.so` are present in the image closure. 165 + 166 + --- 167 + 168 + **Step 5: Inspect environment variables (verifies MM-66.AC3.2 and MM-66.AC3.3)** 169 + 170 + ```bash 171 + docker inspect relay:latest | grep -E 'SSL_CERT_FILE|TZDIR' 172 + ``` 173 + 174 + Expected output (store hash will differ): 175 + 176 + ``` 177 + "SSL_CERT_FILE=/nix/store/...-nss-ca-cert-.../etc/ssl/certs/ca-bundle.crt", 178 + "TZDIR=/nix/store/...-tzdata-.../share/zoneinfo" 179 + ``` 180 + 181 + Both variables must be present. If either is missing, `nix/docker.nix` is missing the `Env` config — re-check Task 1 of Phase 1. 182 + 183 + --- 184 + 185 + **Step 6: Check image size (verifies MM-66.AC4.1)** 186 + 187 + ```bash 188 + docker images relay --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}" 189 + ``` 190 + 191 + Expected: The `SIZE` column shows a value under 50 MB (e.g., `42.3MB`). 192 + 193 + If the size exceeds 50 MB, check `contents` in `nix/docker.nix` for unnecessary packages and remove them. The expected closure is: relay binary + libsqlite3.so + CA bundle + tzdata. No shell, no libc extras. 194 + 195 + --- 196 + 197 + **Step 7: Verify `docker-image` is absent on Darwin (verifies MM-66.AC1.3)** 198 + 199 + From your macOS machine: 200 + 201 + ```bash 202 + nix flake show --accept-flake-config 2>/dev/null | grep docker-image 203 + ``` 204 + 205 + Expected: Lines for `aarch64-linux` and `x86_64-linux` only. No `aarch64-darwin` or `x86_64-darwin` lines appear. 206 + 207 + --- 208 + 209 + **Step 8: Verify flake show on Linux lists both outputs (verifies MM-66.AC1.1 and MM-66.AC1.2)** 210 + 211 + On the Linux system: 212 + 213 + ```bash 214 + nix flake show --accept-flake-config 2>/dev/null | grep docker-image 215 + ``` 216 + 217 + Expected output includes: 218 + ``` 219 + │ ├───aarch64-linux 220 + │ │ ├───docker-image: package 'docker-image.tar.gz' 221 + │ ... 222 + │ ├───x86_64-linux 223 + │ │ ├───docker-image: package 'docker-image.tar.gz' 224 + ``` 225 + 226 + Both `aarch64-linux` and `x86_64-linux` must show `docker-image`. 227 + 228 + <!-- END_TASK_2 --> 229 + 230 + <!-- END_SUBCOMPONENT_A -->
+83
docs/implementation-plans/2026-03-08-MM-66/test-requirements.md
···
··· 1 + # MM-66 Test Requirements 2 + 3 + ## Overview 4 + 5 + MM-66 is a Nix/Docker packaging ticket. There is no Rust application logic under test -- the implementation consists entirely of Nix derivation files (`nix/docker.nix` and a `flake.nix` extension). Consequently, there are no Rust unit tests or integration tests in scope. All verification is operational: checking that Nix flake outputs exist, that the built Docker image loads and runs correctly, and that the image meets size and content constraints. 6 + 7 + Verification splits into two categories: 8 + 9 + 1. **Automated (CI-able on Linux):** Checks that can be scripted and run in a Linux CI environment with Nix and Docker installed. These are shell commands with deterministic expected output. 10 + 2. **Human verification (Linux required):** Checks that require a running Docker daemon on a Linux system. These cannot be run on macOS (where the current development happens) because `docker-image` is intentionally not exposed for Darwin targets. A developer must either use a Linux machine, a remote Linux builder, or a Linux CI runner. 11 + 12 + In practice, every AC in this ticket requires Linux for full verification. The distinction below separates checks that are purely Nix evaluation (can run without Docker) from checks that require both Nix and a Docker daemon. 13 + 14 + ## Automated Tests 15 + 16 + These checks can be scripted in CI. They verify Nix flake structure and file tracking -- no Docker daemon required. 17 + 18 + | AC ID | Test Type | Verification Command | What It Verifies | 19 + |---|---|---|---| 20 + | AC1.3 | Nix flake evaluation (macOS or Linux) | `nix flake show --accept-flake-config 2>/dev/null \| grep docker-image` | `docker-image` appears only under `aarch64-linux` and `x86_64-linux` -- never under `aarch64-darwin` or `x86_64-darwin`. Verifiable on any platform because `nix flake show` evaluates all systems. | 21 + | AC3.4 | Git file tracking | `git ls-files nix/docker.nix` | `nix/docker.nix` exists and is tracked by git (output is `nix/docker.nix`). | 22 + 23 + **Notes:** 24 + - AC1.3 is the only acceptance criterion fully verifiable on macOS. The `nix flake show` output lists all systems regardless of the host platform, so a grep for `docker-image` under Darwin systems can confirm absence. 25 + - AC3.4 is a simple git check with no platform dependency. 26 + 27 + ## Human Verification (Linux Required) 28 + 29 + All remaining ACs require a Linux system with both Nix and Docker installed. The commands below are taken directly from Phase 2, Task 2 of the implementation plan. 30 + 31 + ### AC1: docker-image outputs exist in the flake 32 + 33 + | AC ID | Verification Command | Expected Result | Justification for Human Verification | 34 + |---|---|---|---| 35 + | AC1.1 | `nix flake show --accept-flake-config 2>/dev/null \| grep docker-image` | Output includes `packages.x86_64-linux.docker-image` (or the tree-formatted equivalent showing `docker-image: package 'docker-image.tar.gz'` under `x86_64-linux`) | While `nix flake show` works on any platform, confirming the output is correct on an actual Linux system validates that the conditional evaluation produces the expected attribute. Can be automated in Linux CI. | 36 + | AC1.2 | `nix flake show --accept-flake-config 2>/dev/null \| grep docker-image` | Output includes `packages.aarch64-linux.docker-image` (or the tree-formatted equivalent showing `docker-image: package 'docker-image.tar.gz'` under `aarch64-linux`) | Same as AC1.1. Both architectures must appear. | 37 + 38 + ### AC2: Image builds and loads 39 + 40 + | AC ID | Verification Command | Expected Result | Justification for Human Verification | 41 + |---|---|---|---| 42 + | AC2.1 | `nix build .#docker-image --accept-flake-config` | Exits 0. A `result` symlink appears pointing to a `.tar.gz` in the Nix store. | Requires Linux -- `docker-image` is not a valid flake output on Darwin. The Nix build actually compiles the image derivation. | 43 + | AC2.2 | `nix build .#packages.aarch64-linux.docker-image --accept-flake-config` | Exits 0. A `result` symlink appears for the aarch64 image. | Requires Linux (or cross-compilation with binfmt_misc QEMU support). May need to be verified via CI if no aarch64 system is available. | 44 + | AC2.3 | `docker load < result` | Output contains `Loaded image: relay:latest`. | Requires Docker daemon on Linux. | 45 + | AC2.4 | `docker images relay` | At least one row showing `relay` / `latest`. | Requires Docker daemon on Linux. | 46 + 47 + ### AC3: Image contents 48 + 49 + | AC ID | Verification Command | Expected Result | Justification for Human Verification | 50 + |---|---|---|---| 51 + | AC3.1 | `docker run --rm relay:latest` | Container exits without `no such file or directory` or `error while loading shared libraries: libsqlite3.so` errors. Non-zero exit code is acceptable (relay is a stub). | Requires Docker daemon on Linux. Validates that the relay binary and libsqlite3.so are present in the image closure. | 52 + | AC3.2 | `docker inspect relay:latest \| grep -E 'SSL_CERT_FILE'` | Output shows `SSL_CERT_FILE=/nix/store/...-nss-ca-cert-.../etc/ssl/certs/ca-bundle.crt` (exact store hash varies). | Requires Docker daemon on Linux. Validates the cacert environment variable is set in the image config. | 53 + | AC3.3 | `docker inspect relay:latest \| grep -E 'TZDIR'` | Output shows `TZDIR=/nix/store/...-tzdata-.../share/zoneinfo` (exact store hash varies). | Requires Docker daemon on Linux. Validates the tzdata environment variable is set in the image config. | 54 + 55 + ### AC4: Image size 56 + 57 + | AC ID | Verification Command | Expected Result | Justification for Human Verification | 58 + |---|---|---|---| 59 + | AC4.1 | `docker images relay --format "table {{.Repository}}\t{{.Tag}}\t{{.Size}}"` | SIZE column shows a value under 50 MB. | Requires Docker daemon on Linux. Image must be loaded first (AC2.3). | 60 + 61 + ### AC5: Scope boundaries 62 + 63 + | AC ID | Verification Command | Expected Result | Justification for Human Verification | 64 + |---|---|---|---| 65 + | AC5.1 | `docker run --rm relay:latest` | Container exits (same command as AC3.1). The relay does not attempt to start an HTTP server or listen on a port. No health check endpoint is tested. | Requires Docker daemon on Linux. Confirms the relay is a stub -- packaging only, no HTTP functionality in this ticket. | 66 + 67 + ## AC Coverage Summary 68 + 69 + | AC ID | Description | Category | Phase | Verification Platform | 70 + |---|---|---|---|---| 71 + | AC1.1 | `nix flake show` lists `packages.x86_64-linux.docker-image` | Human (CI-automatable on Linux) | Phase 2, Step 8 | Linux | 72 + | AC1.2 | `nix flake show` lists `packages.aarch64-linux.docker-image` | Human (CI-automatable on Linux) | Phase 2, Step 8 | Linux | 73 + | AC1.3 | `docker-image` absent for Darwin systems | Automated | Phase 1, Task 3 / Phase 2, Step 7 | Any (macOS or Linux) | 74 + | AC2.1 | `nix build .#docker-image` succeeds on x86_64-linux | Human | Phase 2, Step 1 | x86_64-linux | 75 + | AC2.2 | `nix build .#packages.aarch64-linux.docker-image` succeeds | Human | Phase 2, Step 2 | aarch64-linux (or x86_64-linux with binfmt) | 76 + | AC2.3 | `docker load < result` succeeds | Human | Phase 2, Step 3 | Linux (Docker daemon) | 77 + | AC2.4 | `docker images` shows `relay:latest` | Human | Phase 2, Step 3 | Linux (Docker daemon) | 78 + | AC3.1 | `docker run --rm relay:latest` exits without linker errors | Human | Phase 2, Step 4 | Linux (Docker daemon) | 79 + | AC3.2 | `docker inspect` shows `SSL_CERT_FILE` env var | Human | Phase 2, Step 5 | Linux (Docker daemon) | 80 + | AC3.3 | `docker inspect` shows `TZDIR` env var | Human | Phase 2, Step 5 | Linux (Docker daemon) | 81 + | AC3.4 | `nix/docker.nix` tracked by git | Automated | Phase 1, Task 3 | Any | 82 + | AC4.1 | Image size under 50 MB | Human | Phase 2, Step 6 | Linux (Docker daemon) | 83 + | AC5.1 | Relay is a stub; no HTTP server required | Human | Phase 2, Step 4 | Linux (Docker daemon) |

History

4 rounds 0 comments
sign up or login to add to the discussion
9 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
docs(MM-66): commit implementation plans and ignore nix result symlink
fix(MM-66): address PR review — verify-mm66.sh silent failures, comments, CLAUDE.md
docs(MM-66): note NixOS Docker sysctl issue in test plan step 4.1
expand 0 comments
pull request successfully merged
8 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
docs(MM-66): commit implementation plans and ignore nix result symlink
fix(MM-66): address PR review — verify-mm66.sh silent failures, comments, CLAUDE.md
expand 0 comments
7 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
docs(MM-66): commit implementation plans and ignore nix result symlink
expand 0 comments
6 commits
expand
docs: add MM-66 Docker image design plan
feat(MM-66): add nix/docker.nix and expose docker-image on Linux
docs(MM-66): note docker-image is Linux-only in CLAUDE.md
docs(MM-66): add nix/ directory to project structure in CLAUDE.md
test(MM-66): add automated verification script for AC1.3 and AC3.4
docs: add test plan for MM-66 Docker image
expand 0 comments