hyperhive/nix/docs/default.nix
iris a05d686875 docs: split swarm/deploy options into their own reference pages
services.hyperhive.swarm.* used to carry both swarm-wide facts (name,
domain, hives, ca) and the 'does THIS host run it' toggles for every
swarm service. deploy.nix already split those toggles out into their
own services.hyperhive.deploy.* namespace; this is the docs-side
follow-up now that swarm.* is genuinely swarm-wide-only.

nix/docs/default.nix: host.md drops the swarm/deploy subtrees
(builtins.removeAttrs on the already-picked host tree, not
lib.recursiveUpdate -- that merges rather than deletes, which would
have silently kept them on host.md); swarm.md and deploy.md are new
markdown pages, each its own pickSubtrees root. nix/packages/default.nix
exposes docs-swarm/docs-deploy as flake outputs alongside the existing
docs-host/docs-agent. docs/gotchas.md's Nix options reference section
and docs/swarm/README.md get pointers to the new split.
2026-08-30 04:32:01 +02:00

248 lines
8.6 KiB
Nix

{
pkgs,
lib,
self,
nixosSystem,
}:
# Nix options reference: `pkgs.nixosOptionsDoc` over two evaluated
# module trees, emitted as CommonMark (`host.md` + `agent.md` +
# `swarm.md` + `deploy.md`). The HTML + CSS for `/options/` is rendered
# downstream by the website repo, which owns the presentation and
# shares one stylesheet with the prose `/docs/` tree. Full pipeline +
# subtree-pick / output-tree rationale: docs/gotchas.md::Nix options
# reference.
#
# `swarm.md`/`deploy.md` split off `host.md` (mara: "move swarm options
# to new docs page... deploy.* is also one of the things that should be
# a sub page"): `services.hyperhive.swarm.*` was mixed — swarm-wide
# facts (name, domain, hives, ca) alongside "does THIS host run it"
# toggles — until `deploy.nix` moved every such toggle to its own flat
# `services.hyperhive.deploy.*` namespace. That reorg landed first
# (see deploy.nix's file-top comment); this is the docs-side follow-up
# now that `swarm.*` genuinely is swarm-wide-only.
let
# Content-addressed narrow source covering only the nix/ directory.
# `builtins.unsafeDiscardStringContext` strips `self`'s store-path
# context so `builtins.path` hashes only the nix/ file content, not
# the full flake source (Rust, frontend, markdown, …). Result: the
# docs drvs only change when a .nix file changes, not on every
# commit — the muede-pc2 remote builder can reuse its cached result
# for any commit that doesn't touch nix/.
nixSrc = builtins.path {
path = builtins.unsafeDiscardStringContext (toString self + "/nix");
name = "hyperhive-nix-src";
};
# Stub host system: every hyperhive subsystem `mkForce false` so
# heavy build inputs (matrix container, forge, etc.) stay out of
# the eval — only option *declarations* matter for the doc walk.
# Import the host-module aggregator from the content-addressed
# nixSrc; the package options (`services.hyperhive.c0re.package`
# etc.) carry no in-module defaults, but with hyperhive disabled
# nothing reads them, so no stubs are needed.
hostEval = nixosSystem {
system = pkgs.stdenv.hostPlatform.system;
modules = [
"${nixSrc}/host-modules"
(
{ lib, ... }:
{
fileSystems."/" = {
device = "/dev/null";
fsType = "tmpfs";
};
boot.loader.grub.enable = false;
system.stateVersion = "25.11";
services.hyperhive.enable = lib.mkForce false;
services.hyperhive.swarm.matrix.enable = lib.mkForce false;
}
)
];
};
# Agent module eval from the content-addressed nixSrc. Relative
# imports inside agent.nix (the ../agent-modules dir) resolve
# correctly against the nixSrc directory tree. `hyperhive.packages`
# stays unset — every option default that references it carries a
# `defaultText`, so the doc walk never forces the packages.
agentEval = nixosSystem {
system = pkgs.stdenv.hostPlatform.system;
modules = [
"${nixSrc}/templates/agent.nix"
];
};
# Rewrite option declaration paths from nix-store absolute paths to
# forge URLs so rendered docs link back to source.
# nixSrc is a content-addressed copy of nix/; strip its store prefix
# and prepend nix/ to recover the repo-relative path.
forgeRoot = "https://forge.darkest.space/hyperhive/hyperhive/src/branch/main";
nixSrcPrefix = builtins.unsafeDiscardStringContext (toString nixSrc + "/");
transformOptions =
opt:
opt
// {
declarations = map (
decl:
let
declStr = toString decl;
relPath =
if lib.hasPrefix nixSrcPrefix declStr then
"nix/" + lib.removePrefix nixSrcPrefix declStr
else
baseNameOf declStr;
in
{
url = "${forgeRoot}/${relPath}";
name = relPath;
}
) opt.declarations;
};
# Filter to a set of top-level subtree roots — keeps the rendered docs
# focused on hyperhive's surface instead of NixOS's 10k+ default
# options. Root choice matters: see docs/gotchas.md::Nix options
# reference for the services.hyperhive consolidation history.
pickSubtrees =
options: roots:
let
pick =
path:
if lib.hasAttrByPath path options then
lib.setAttrByPath path (lib.getAttrFromPath path options)
else
{ };
in
lib.foldl' lib.recursiveUpdate { } (map pick roots);
hostOptionsFull = pickSubtrees hostEval.options [
[
"services"
"hyperhive"
]
];
# `swarm.*` and `deploy.*` get their own pages below — drop them from
# the host tree rather than duplicating them here too. `pickSubtrees`
# only ever picked `services.hyperhive` for `hostOptionsFull` (nothing
# else lives under `services` in this tree), so a direct replacement
# is correct here — NOT `lib.recursiveUpdate`, which merges rather
# than deletes: a key present on the left and absent on the right
# survives the "update," which would silently keep `swarm`/`deploy`
# on `host.md` instead of dropping them.
hostOptions = {
services.hyperhive = builtins.removeAttrs hostOptionsFull.services.hyperhive [
"swarm"
"deploy"
];
};
swarmOptions = pickSubtrees hostEval.options [
[
"services"
"hyperhive"
"swarm"
]
];
deployOptions = pickSubtrees hostEval.options [
[
"services"
"hyperhive"
"deploy"
]
];
agentOptions = pickSubtrees agentEval.options [
[ "hyperhive" ]
];
hostDoc = pkgs.nixosOptionsDoc {
options = hostOptions;
inherit transformOptions;
};
swarmDoc = pkgs.nixosOptionsDoc {
options = swarmOptions;
inherit transformOptions;
};
deployDoc = pkgs.nixosOptionsDoc {
options = deployOptions;
inherit transformOptions;
};
agentDoc = pkgs.nixosOptionsDoc {
options = agentOptions;
inherit transformOptions;
};
# CommonMark `.md` is the source of truth and the only output. HTML
# rendering + theming lives in the website repo (it owns the
# presentation + shares one stylesheet across `/options/` and
# `/docs/`); this flake just emits the option reference as markdown.
mkMarkdownPage =
name: title: doc:
pkgs.runCommand "hyperhive-${name}.md" { } ''
{
echo "# ${title}"
echo
echo "<!-- Auto-generated from the hyperhive flake."
echo " Source: nix/docs/default.nix · regenerate with"
echo " \`nix build .#${name}\` -->"
echo
cat ${doc.optionsCommonMark}
} > $out
'';
# Bundle landing page — a short markdown index pointing at the four
# reference pages.
indexMD = pkgs.writeText "hyperhive-options-index.md" ''
# hyperhive nix options reference
Auto-generated from the hyperhive flake. Four reading paths:
- [host options](host.md) options exposed by
`hyperhive.nixosModules.default` to operator host configurations
(`services.hyperhive.{enable,domain,c0re,gateway,tls,network}.*`).
- [swarm options](swarm.md) swarm-wide facts, identical on every
host in the swarm (`services.hyperhive.swarm.{name,domain,hives,
ca,forge,matrix}.*`).
- [deploy options](deploy.md) this host's own deployment
decisions, necessarily different per host
(`services.hyperhive.deploy.*` does *this* machine run
grafana, the swarm controller, authelia, ).
- [per-agent options](agent.md) options declared in
`nix/agent-modules/`, visible from every `agent.nix`
(`hyperhive.model`, `hyperhive.allowedRecipients`,
`hyperhive.extraMcpServers`, `hyperhive.frontend.*`,
`hyperhive.forge.*`, `hyperhive.matrix.*`, `hyperhive.gui.*`).
Regenerate with `nix build .#docs` (bundle), `.#docs-host`,
`.#docs-swarm`, `.#docs-deploy`, or `.#docs-agent`. Consumed by the
website repo to render `/options/`.
'';
hostMD = mkMarkdownPage "docs-host" "hyperhive host options" hostDoc;
swarmMD = mkMarkdownPage "docs-swarm" "hyperhive swarm options" swarmDoc;
deployMD = mkMarkdownPage "docs-deploy" "hyperhive deploy options" deployDoc;
agentMD = mkMarkdownPage "docs-agent" "hyperhive per-agent options" agentDoc;
in
{
host = hostMD;
swarm = swarmMD;
deploy = deployMD;
agent = agentMD;
# Bundle of the option reference as markdown. The website renders
# these `.md` to themed HTML for `/options/`; standalone consumers
# get the CommonMark source directly.
bundle = pkgs.runCommand "hyperhive-options-docs" { } ''
mkdir -p $out
cp ${indexMD} $out/index.md
cp ${hostMD} $out/host.md
cp ${swarmMD} $out/swarm.md
cp ${deployMD} $out/deploy.md
cp ${agentMD} $out/agent.md
'';
}