Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Every tag has its own section, release candidates included, and the release work

## [Unreleased]

Nothing has been released yet. This section records what `main` holds after the September 2026 stack (#13, #16 to #21, #23), compared with the May 2026 tree (`aa7a5a8`) that anyone following `main` before it had.
Nothing has been released yet. This section records what `main` holds after the pull requests merged in September 2026 (#13 to #68), compared with the May 2026 tree (`aa7a5a8`) that anyone following `main` before them had.

### Breaking

Expand Down Expand Up @@ -38,6 +38,18 @@ Nothing has been released yet. This section records what `main` holds after the
- New checks built in CI: the NixOS VM tests `vmTest-0_6`, `vmTestWithHapp-0_6` (#16), `vmTestConductorMetrics-0_6`, `vmTestWindtunnel` (#17) and `vmTestGateway` (#18), and `conductorMetricsJq` (#21).
- The example fleet runs Holochain 0.6.3 with hREA happ-0.4.0-beta, Kando v0.17.5 and Requests & Offers v0.5.2, fetched by hash. The hardware stubs of the example and of the `fleet` template carry the HoloPort disk layout (GPT with a `bios_grub` partition and an ESP, GRUB for both firmwares). (#19, #21)
- `CONTRIBUTING.md`, with the VM-test and option-reference rules. (#18)
- `services.holochain-edgenode.binaryCache.enable`, on by default: a host importing the module gets the Holochain Foundation cache (`holochain-ci.cachix.org`) and its key in `nix.settings`, so `holochain` and `hc` download prebuilt after the first switch. (#34)
- Per-DHT series from `dump-network-metrics --include-dht-summary`: `holochain_dht_*`, one set per cell, labelled `conductor`, `app_id`, `role` and `dna`, and named for dashboards by `holochain_dht_info` and `holochain_app_info`, from the new `happs.<id>.displayName` and `roleNames`. (#47, #63)
- `packages.<system>.holochain-conductor-exporter` and `holochain-conductor-exporter-0_6`, the one program that writes `holochain_*` series for any conductor on a machine. Every series carries a `conductor` label, from the new `conductorMetrics.name` (default `"Holochain"`). (#63)
- `holochain-grafana`: recording rules that compute every state once (`modules/holochain-rules.nix`), with their thresholds in `states`; `scrapeTargets` as an attribute set keyed by node name, with an optional `site` (a list still works); `overviewUnits` with the name a person reads for each unit; and `room`. (#35, #64)
- Five dashboards, each titled with its reader's question and all tagged `holochain`: `holochain-home` ("What is this machine running?", Grafana's home page, opening on the machine Grafana runs on), `holochain-now`, `holochain-fleet` (now "Which Holochain node needs attention?"), `holochain-node` and `holochain-network`. (#35, #65, #67)
- `services.holochain-services`: every module lists the units it installs, by name and with the version it runs, and the dashboards show each one's state; a timer reads the bootstrap server's `/health`. (#66, #67)
- `nixosModules.holochain-bootstrap`, the Kitsune2 bootstrap and relay server as a service, with `packages.<system>.bootstrap-srv` and `bootstrap-srv-0_6`. The edgenode gains `relayAllowPlainText`, `requestTimeoutS`, `dbSyncLevel` and `wasmBackend`. (#62)
- `nixosModules.sensorica-event-node`, the Sensorica workshop profile: Holochain 0.6.3 with hREA, Kando and Requests & Offers on one network seed. Not part of `nixosModules.default`. (#59)
- `packages.x86_64-linux.wdocker-0_15`, Moss `wdocker` from tag v0.15.8 with the Holochain 0.6.1 it pins (#60), and `nixosModules.holochain-moss-node`, a Moss group's always-online node as a service, with its readings and its Grafana page (#67). Not part of `nixosModules.default`.
- `packages.x86_64-linux.holoport-install`, which erases one disk, lays it out as ADR-017 says and installs a system that boots on legacy BIOS and on UEFI. (#61)
- More checks built in CI: the VM tests `vmTestWdocker` (#60), `vmTestHoloportInstall` (#61), `vmTestBootstrap` (#62), `vmTestServices` and `vmTestServices-noBootstrap` (#66) and `vmTestMossNode` (#67); without a VM, `edgenodeBinaryCache` (#34), `dhtMetricsJq` (#47), `edgenodeConfigRender` (#62), `metricsHelpAgreement`, `metricsNameShape` and `edgenodeNamesWiring` (#63), `holochainRules` and `grafanaProvisioning` (#64), `dashboardLabels`, `dashboardWords` and `dashboardQueries` (#65), `moss-dashboard` and `moss-names` (#67).
- The MIT `LICENSE` (#36); `SECURITY.md`, issue forms and a pull request template (#48); this changelog and a tag-driven release workflow (#49); the design record in `docs/adr/` (#51); and the documentation book, built from `docs/` and published at <https://sensorica.github.io/nixos-holochain/> (#67).

### Changed

Expand All @@ -47,11 +59,15 @@ Nothing has been released yet. This section records what `main` holds after the
- The boot loader moved out of the placeholder `hardware-configuration.nix` files into `configuration.nix` and `hosts/common.nix`, so replacing a stub with `nixos-generate-config` output keeps it. `#minimal` targets a stock UEFI install with systemd-boot. (#21)
- The fleet template and the example put one `operatorKeys` list on the operator account and on root, so Colmena can log in. (#21)
- The example fleet's lock follows `main` after the stack instead of the May tree. (#23)
- The `holochain_conductor_*_total` counters are running totals across closed connections instead of sums over the connections open at that moment, and the metrics timer also calls `list-apps` and `dump-network-metrics`. (#35, #47)
- `nixosModules.default` also imports `holochain-bootstrap`, which is off until enabled. (#62)
- The example fleet's hosts are `sensorica-holoport-01` to `sensorica-holoport-05`, take their Holochain line and hApps from `sensorica-event-node`, and gain an operator desk, per-host switches and the Moss node on `sensorica-holoport-01`. Its `nixos-holochain` input follows `main`. (#59, #67, #68)

### Fixed

- The hApp installer treats a failed `list-apps` while the conductor compiles wasm as "not yet" instead of ending the unit, and no fixed start timeout caps `installerTimeout`. (#16, #21)
- The metrics jq sums `blocked_message_counts` at any depth; it used to write a JSON object into the textfile, which made node_exporter drop every `holochain_*` series. (#21)
- The gateway's `--address` is shell-escaped. (#21)
- The metrics timer no longer hands the whole `list-apps` reply to jq as one argument, which Linux caps at 128 KiB: a large reply stopped the script before it wrote anything. (#47)

[Unreleased]: https://github.com/Sensorica/nixos-holochain/commits/main
52 changes: 23 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

> A declarative substrate for running Holochain edgenodes, hApps, and developer environments. Built at Sensorica, intended for the Holochain community.

**Status:** the modules work and are VM-tested. A conductor and its hApps come up at boot on both supported Holochain lines (0.7.0 and 0.6.3), a fleet's traffic is on a provisioned Grafana dashboard, and an HTTP gateway serves zome reads over HTTP. Ten NixOS VM tests run in CI. What is still open is hardware: the five-machine fleet has not been deployed to real Holoports yet (issues [#8](https://github.com/Sensorica/nixos-holochain/issues/8) to [#12](https://github.com/Sensorica/nixos-holochain/issues/12)).
**Status:** the modules work and are VM-tested. A conductor and its hApps come up at boot on both supported Holochain lines (0.7.0 and 0.6.3), a fleet's traffic is on a provisioned Grafana dashboard, and an HTTP gateway serves zome reads over HTTP. Fourteen NixOS VM tests run in CI. What is still open is hardware: one Holoport, `sensorica-holoport-01`, was installed from the [runbook](docs/deployment.md#installing-on-a-holoport-legacy-bios) on 2026-09-27, and the five-machine fleet is not deployed yet (issues [#8](https://github.com/Sensorica/nixos-holochain/issues/8) to [#12](https://github.com/Sensorica/nixos-holochain/issues/12)).
**License:** [MIT](LICENSE), the license of nixpkgs, so any module here can be reused in other flakes or proposed upstream to nixpkgs as it is. The hApps these modules run keep their own licenses (Holochain itself and Moss are CAL-1.0, hREA is Apache-2.0).
**Origin:** Successor to the archived [Sensorica/holoports-workshop](https://github.com/Sensorica/holoports-workshop), pivoting from HolOS appliance-image deployment to vanilla NixOS authorship.
**Documentation:** the book at [sensorica.github.io/nixos-holochain](https://sensorica.github.io/nixos-holochain/), built from `docs/` with mdBook.
Expand Down Expand Up @@ -97,44 +97,32 @@ See [`docs/deployment.md`](docs/deployment.md) for the deployment guide, [`docs/

```
nixos-holochain/
├── flake.nix # Entry point: inputs, modules, templates, packages, VM checks
├── modules/
│ ├── holochain-edgenode.nix # Core: conductor + lair + hApp installer + metrics
│ ├── conductor-metrics.jq # dump-network-stats → Prometheus text
│ ├── conductor-counters.jq # running byte and message totals across closed connections
│ ├── dht-metrics.jq # list-apps + dump-network-metrics → per-DHT Prometheus text
│ ├── holochain-grafana.nix # Prometheus + Grafana for a fleet
│ ├── dashboards/ # Provisioned Grafana dashboards
│ ├── holochain-windtunnel.nix # Opt-in: donate the machine to the Foundation's Nomad cluster
│ ├── holochain-http-gateway.nix # HTTP gateway in front of the conductor
│ └── default.nix # Module aggregator
├── packages/
│ ├── holochain-http-gateway.nix # hc-http-gw build, one release per Holochain line
│ └── wdocker.nix # Moss always-online node, with the Holochain it expects
├── flake.nix # Entry point: inputs, modules, templates, packages, checks
├── modules/ # The NixOS modules, with the exporters, recording rules and dashboards they ship
├── packages/ # hc-http-gw per Holochain line, the conductor exporter, Moss wdocker
├── templates/
│ ├── minimal/ # nix flake init -t …#minimal: one edgenode
│ └── fleet/ # nix flake init -t …#fleet: five nodes, Grafana, live ISO
├── examples/
│ └── sensorica-fleet/ # The Sensorica Lab fleet: its own flake, five hosts, ISO, colmena hive
│ ├── flake.nix
│ ├── hosts/common.nix # shared host config, operator SSH keys
│ ├── hosts/sensorica-holoport-01..05/ # configuration.nix + hardware-configuration.nix per machine
│ ├── hosts/workshop-iso/ # Live ISO for participants
│ └── README.md
│ └── sensorica-fleet/ # The Sensorica Lab fleet: its own flake, five Holoports, ISO, Colmena hive (layout in its README)
├── tests/ # Fixtures and the checks that need no VM
├── happs/ # .happ bundles (not committed, see happs/README.md)
├── secrets/ # private material only, gitignored except *.example
├── CHANGELOG.md # One section per release, published as its release note
├── scripts/
│ └── changelog-section.sh # Prints one version's CHANGELOG section
│ ├── changelog-section.sh # Prints one version's CHANGELOG section
│ └── holoport-install.sh # Erases one disk and installs a system that boots on a Holoport
├── workshop/
│ ├── facilitator-guide.md
│ ├── participant-handout.md
│ └── preflight-checklist.md
├── book.toml # The documentation book, built from docs/ with mdBook
└── docs/
├── architecture.md
├── introduction.md # The book's first page; SUMMARY.md is its table of contents
├── architecture.md # How the pieces fit, with every file under modules/ and packages/
├── module-options.md # generated by `nix build .#options-doc`
├── deployment.md
├── moss-node.md # running the packaged Moss node by hand
├── moss-node.md # the Moss always-online node, as a service and by hand
├── releasing.md # How a maintainer cuts a release candidate and a release
├── adr/ # architecture decision records, one per file
├── images/ # dashboard screenshots
Expand All @@ -152,6 +140,8 @@ nixos-holochain/
| `holochain-http-gateway` | `hc-http-gw` in front of the conductor, exposing named zome functions over HTTP. Nothing is exposed by default. |
| `holochain-windtunnel` | Opt-in, off by default: joins the machine to the Holochain Foundation's Nomad cluster to run their Wind Tunnel scenarios. |
| `holochain-bootstrap` | The Kitsune2 bootstrap and relay server on your own machine, so a fleet finds itself without the Foundation's test server or the internet. See [Running your own bootstrap and relay](docs/deployment.md#running-your-own-bootstrap-and-relay). |
| `holochain-moss-node` | A Moss group's always-online node as a service, beside the edgenode, with its readings and its own Grafana page. Not part of `nixosModules.default`, because it runs a second conductor. See [`docs/moss-node.md`](docs/moss-node.md). |
| `sensorica-event-node` | The Sensorica workshop's profile layered on `holochain-edgenode`: Holochain 0.6.3, hREA, Kando and Requests & Offers on one network seed. Not part of `nixosModules.default`. See [`examples/sensorica-fleet/README.md`](examples/sensorica-fleet/README.md#holochain-line-and-happs). |

Key options for `services.holochain-edgenode`:

Expand All @@ -168,25 +158,29 @@ Key options for `services.holochain-edgenode`:
| `conductorMetrics.enable` | `false` | The conductor's own `holochain_*` series |
| `openFirewall` | `false` | Open firewall ports |

The full reference for all five modules is [`docs/module-options.md`](docs/module-options.md), generated from the declarations by `nix build .#options-doc`.
The full reference for `holochain-edgenode`, `holochain-grafana`, `holochain-http-gateway`, `holochain-windtunnel`, `holochain-bootstrap` and `holochain-services` (the list of services every module feeds to the dashboards) is [`docs/module-options.md`](docs/module-options.md), generated from the declarations by `nix build .#options-doc`. The Moss node's options are in [`docs/moss-node.md`](docs/moss-node.md#as-a-nixos-service); `sensorica-event-node` declares none.

---

## Tests

Ten NixOS VM tests and a conductor config check, all built in CI:
Fourteen NixOS VM tests, all built in CI: thirteen in the `nix flake check` job, and `vmTestHoloportInstall` in a job of its own because it copies a whole system onto a virtual disk ([`.github/workflows/ci.yml`](.github/workflows/ci.yml)).

| Check | What it proves |
|---|---|
| `vmTest` / `vmTest-0_6` | A bare conductor comes up and answers `list-apps` on 0.7.0 and on 0.6.3 |
| `vmTestWithHapp` / `vmTestWithHapp-0_6` | A hApp installs once, stays enabled, and survives a cold boot on both lines, and every one of its cells has its `holochain_dht_*` series on `/metrics` |
| `vmTestConductorMetrics-0_6` | The conductor's gauges appear on `/metrics` on the 0.6 line |
| `vmTestGrafana` | Conductor and per-DHT series reach Prometheus, the five dashboards are provisioned with their data source and "What is this machine running?" is Grafana's home page, opening on this machine, every service its modules list carries its version, every panel query answers through Grafana's own query API (three are only required not to error: the two temperature panels, since a VM has no sensor, and "Same data everywhere", which needs two nodes), and the pages name a failed unit, a dead node and a stale, silent or unreadable conductor as such |
| `vmTestServices` / `vmTestServices-noBootstrap` | The node page names exactly the services the enabled modules installed, each Running; a bootstrap server frozen, stopped or failing reads Not answering, Stopped or Failed, and the room screen's tile reads "A service is down"; without the server, the same list less that one |
| `vmTestGateway` | A zome read answers 200 with JSON through the HTTP gateway, and a function outside the allow list answers 403 |
| `vmTestWindtunnel` | The generated container unit carries the flags the runner requires, and stays stopped when `autoStart = false` |
| `vmTestWdocker` | The packaged Moss `wdocker` starts its pinned Holochain 0.6.1 conductor through `wdaemon` in an offline VM, downloads nothing into its `bins` directory, and `wdocker stop` ends the conductor |
| `vmTestMossNode` | The Moss node service starts with no terminal, reads its password from a credential, survives a restart and reports `holochain_conductor_up{conductor="Moss"} 1`; with no password file it never starts, and an empty one is refused |
| `vmTestBootstrap` | Two 0.6 edgenodes with no internet find each other through a `holochain-bootstrap` server and its plain-HTTP relay; its falsifier, with one node on the wrong port, must fail |
| `edgenodeConfigRender` | `relayAllowPlainText`, `requestTimeoutS`, `dbSyncLevel` and `wasmBackend` render on each line, and that line's real conductor starts on the result |
| `vmTestHoloportInstall` | `holoport-install` lays out an empty SATA disk the ADR-017 way and installs `sensorica-holoport-01` on it; the disk then boots under SeaBIOS, which is legacy BIOS like a Holoport, with GRUB for both firmwares, the conductor active and the three workshop hApps enabled once each |

The checks without a VM are built in the same job: `edgenodeConfigRender` (`relayAllowPlainText`, `requestTimeoutS`, `dbSyncLevel` and `wasmBackend` render on each line, and that line's real conductor starts on the result), the exporter checks (`conductorMetricsJq`, `dhtMetricsJq`, `metricsHelpAgreement`, `metricsNameShape`, `edgenodeNamesWiring`), the Grafana checks (`holochainRules`, `grafanaProvisioning`, `dashboardLabels`, `dashboardWords`, `dashboardQueries`), the Moss checks (`moss-dashboard`, `moss-names`), and `edgenodeBinaryCache`, which `nix flake check` settles at evaluation.

```bash
nix flake check --no-build --all-systems
Expand Down Expand Up @@ -227,7 +221,7 @@ Each ticked item names the pull request that closed it.
- [ ] Validated on a physical machine ([#8](https://github.com/Sensorica/nixos-holochain/issues/8))

**Phase 2: workshop ready**
- [x] `holochain-grafana`: Prometheus and Grafana with the "Holochain Fleet" dashboard and its data source provisioned (#17)
- [x] `holochain-grafana`: Prometheus and Grafana with the fleet dashboard (`holochain-fleet`) and its data source provisioned (#17)
- [x] `conductorMetrics`: the conductor's own network stats as `holochain_*` series, on both lines (#17)
- [x] The example fleet exports metrics on all five nodes, with the Wind Tunnel runner off in writing (#17)
- [x] `holochain-windtunnel`: the Foundation's runner image, off by default, with what enabling it costs written into the option (#17)
Expand All @@ -245,7 +239,7 @@ Each ticked item names the pull request that closed it.
- [x] `CONTRIBUTING.md` with the VM-test and options-doc rules (#18)
- [ ] hAppenings Community Substack announcement
- [ ] hREA module (composable with the edgenode module)
- [ ] Documentation site
- [x] Documentation site: the book at [sensorica.github.io/nixos-holochain](https://sensorica.github.io/nixos-holochain/) (#67)

**Phase 4: production hardening**
- [ ] sops-nix integration for secrets
Expand Down
Loading
Loading