nix: add options docs outputs for host + agent surfaces (#616)
Auto-generate CommonMark references for hyperhive's two NixOS module surfaces via `pkgs.nixosOptionsDoc`: - `packages.<system>.docs-host` — operator-facing options exposed by `hyperhive.nixosModules.default` (`services.hive-c0re.*`, `hyperhive.domain`, `hyperhive.forge.*`, `hyperhive.matrix.*`). - `packages.<system>.docs-agent` — per-agent options declared in `nix/templates/harness-base.nix` (model, allowedRecipients, extraMcpServers, frontend, forge, matrix, gui, …). - `packages.<system>.docs` — both pages plus a thin `README.md` index, bundled for publishing. Declaration links are rewritten to point at the forge source tree instead of nix-store paths. Host options come from a stubbed `nixosSystem` eval that force-disables all hyperhive subsystems — only the *declarations* feed the doc renderer, no heavy build inputs end up in the closure. Agent options reuse `nixosConfigurations.agent-base.options` (already evaluated). Also wired as `checks.<system>.docs` so CI fails fast on eval breakage.
This commit is contained in:
parent
d074b25fac
commit
6a64770c79
2 changed files with 206 additions and 0 deletions
29
flake.nix
29
flake.nix
|
|
@ -115,6 +115,13 @@
|
||||||
nativeBuildInputs,
|
nativeBuildInputs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
|
let
|
||||||
|
docsAttrs = import ./nix/docs.nix {
|
||||||
|
inherit pkgs self;
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
inherit (nixpkgs.lib) nixosSystem;
|
||||||
|
};
|
||||||
|
in
|
||||||
{
|
{
|
||||||
# Build the workspace binaries without running tests. Tests
|
# Build the workspace binaries without running tests. Tests
|
||||||
# are run as a separate check (`checks.cargo-test`) that
|
# are run as a separate check (`checks.cargo-test`) that
|
||||||
|
|
@ -167,6 +174,15 @@
|
||||||
# host would only succeed via a remote x86 builder.
|
# host would only succeed via a remote x86 builder.
|
||||||
agent-base-toplevel = self.nixosConfigurations.agent-base.config.system.build.toplevel;
|
agent-base-toplevel = self.nixosConfigurations.agent-base.config.system.build.toplevel;
|
||||||
manager-toplevel = self.nixosConfigurations.manager.config.system.build.toplevel;
|
manager-toplevel = self.nixosConfigurations.manager.config.system.build.toplevel;
|
||||||
|
|
||||||
|
# Auto-generated nix options reference for hyperhive (#616).
|
||||||
|
# `docs` bundles host + agent pages into one tree; the split
|
||||||
|
# outputs are useful when consumers only want one surface.
|
||||||
|
# All three are pure markdown — no rust or frontend deps in
|
||||||
|
# the closure, so `nix build .#docs` is cheap.
|
||||||
|
docs = docsAttrs.bundle;
|
||||||
|
docs-host = docsAttrs.host;
|
||||||
|
docs-agent = docsAttrs.agent;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -328,6 +344,19 @@
|
||||||
cargoTestExtraArgs = "--workspace";
|
cargoTestExtraArgs = "--workspace";
|
||||||
HIVE_ASSETS_DIR = "${self.packages.${system}.assets}/share/hyperhive";
|
HIVE_ASSETS_DIR = "${self.packages.${system}.assets}/share/hyperhive";
|
||||||
};
|
};
|
||||||
|
# Nix options docs evaluation (#616). Cheap: pulls in
|
||||||
|
# `nixosOptionsDoc` + the host module's stub eval, no rust or
|
||||||
|
# frontend deps. CI fails fast if a module change breaks
|
||||||
|
# option declarations or the doc rendering. `docs-host` +
|
||||||
|
# `docs-agent` are exposed as `packages` outputs (not checks)
|
||||||
|
# — they share this eval, so building the bundle here covers
|
||||||
|
# both surfaces in one shot.
|
||||||
|
docs =
|
||||||
|
(import ./nix/docs.nix {
|
||||||
|
inherit pkgs self;
|
||||||
|
inherit (nixpkgs) lib;
|
||||||
|
inherit (nixpkgs.lib) nixosSystem;
|
||||||
|
}).bundle;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
177
nix/docs.nix
Normal file
177
nix/docs.nix
Normal file
|
|
@ -0,0 +1,177 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
self,
|
||||||
|
nixosSystem,
|
||||||
|
}:
|
||||||
|
# Options documentation for hyperhive's NixOS module surfaces.
|
||||||
|
# Closes #616.
|
||||||
|
#
|
||||||
|
# Two output trees:
|
||||||
|
# docs-host — operator-facing options exposed by the meta module
|
||||||
|
# (`hyperhive.nixosModules.default`). Covers
|
||||||
|
# `hyperhive.*` (domain, enable, c0re, forge, matrix)
|
||||||
|
# plus the deprecated `services.hive-c0re.*` alias.
|
||||||
|
# docs-agent — per-agent options declared by the shared harness
|
||||||
|
# module (`nix/templates/harness-base.nix`, transitively
|
||||||
|
# imported by `agent-base.nix` and `manager.nix`).
|
||||||
|
# Covers `hyperhive.*` (model, allowedRecipients,
|
||||||
|
# extraMcpServers, frontend, forge, matrix, gui, …).
|
||||||
|
#
|
||||||
|
# Both render as CommonMark via `pkgs.nixosOptionsDoc`. `docs` bundles
|
||||||
|
# them into one derivation alongside a small `README.md` index so it
|
||||||
|
# can be published verbatim.
|
||||||
|
let
|
||||||
|
# Evaluate the host module under a stub NixOS system. Stubs satisfy
|
||||||
|
# the few hard-required options (filesystems, stateVersion) without
|
||||||
|
# actually enabling the hive — we only want the option *declarations*
|
||||||
|
# to evaluate, not the config.
|
||||||
|
hostEval = nixosSystem {
|
||||||
|
system = pkgs.stdenv.hostPlatform.system;
|
||||||
|
modules = [
|
||||||
|
self.nixosModules.default
|
||||||
|
(
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
nixpkgs.overlays = [ self.overlays.default ];
|
||||||
|
fileSystems."/" = {
|
||||||
|
device = "/dev/null";
|
||||||
|
fsType = "tmpfs";
|
||||||
|
};
|
||||||
|
boot.loader.grub.enable = false;
|
||||||
|
system.stateVersion = "25.11";
|
||||||
|
# Force-disable every hyperhive subsystem so config evaluation
|
||||||
|
# doesn't pull in heavy build inputs (matrix container, forge,
|
||||||
|
# etc.). Options are still fully declared either way — that's
|
||||||
|
# what nixosOptionsDoc traverses.
|
||||||
|
services.hive-c0re.enable = lib.mkForce false;
|
||||||
|
hyperhive.forge.enable = lib.mkForce false;
|
||||||
|
hyperhive.matrix.enable = lib.mkForce false;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
# Agent options live in the already-evaluated `agent-base` container
|
||||||
|
# config. Reusing it avoids re-evaluating the harness module against
|
||||||
|
# a fresh stub — the options tree is identical to what a real agent
|
||||||
|
# container sees.
|
||||||
|
agentEval = self.nixosConfigurations.agent-base;
|
||||||
|
|
||||||
|
# Strip the nix-store prefix from option declaration paths and rewrite
|
||||||
|
# them as forge URLs so the rendered docs link back to the source.
|
||||||
|
forgeRoot = "https://forge.darkest.space/hyperhive/hyperhive/src/branch/main";
|
||||||
|
storePrefix = toString self + "/";
|
||||||
|
transformOptions =
|
||||||
|
opt:
|
||||||
|
opt
|
||||||
|
// {
|
||||||
|
declarations = map (
|
||||||
|
decl:
|
||||||
|
let
|
||||||
|
declStr = toString decl;
|
||||||
|
relPath =
|
||||||
|
if lib.hasPrefix storePrefix declStr then
|
||||||
|
lib.removePrefix storePrefix declStr
|
||||||
|
else
|
||||||
|
baseNameOf declStr;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
url = "${forgeRoot}/${relPath}";
|
||||||
|
name = relPath;
|
||||||
|
}
|
||||||
|
) opt.declarations;
|
||||||
|
};
|
||||||
|
|
||||||
|
# Filter an evaluated `options` tree down to a set of top-level
|
||||||
|
# subtrees we care about. Anything outside the listed roots is
|
||||||
|
# dropped — keeps the rendered docs focused on hyperhive's surface
|
||||||
|
# instead of NixOS's 10k+ default options.
|
||||||
|
pickSubtrees =
|
||||||
|
options: roots:
|
||||||
|
let
|
||||||
|
walk =
|
||||||
|
path: tree:
|
||||||
|
if path == [ ] then
|
||||||
|
lib.getAttrFromPath path options
|
||||||
|
else
|
||||||
|
lib.setAttrByPath path (lib.getAttrFromPath path tree);
|
||||||
|
pick =
|
||||||
|
path:
|
||||||
|
let
|
||||||
|
exists = lib.hasAttrByPath path options;
|
||||||
|
in
|
||||||
|
if exists then lib.setAttrByPath path (lib.getAttrFromPath path options) else { };
|
||||||
|
in
|
||||||
|
lib.foldl' lib.recursiveUpdate { } (map pick roots);
|
||||||
|
|
||||||
|
hostOptions = pickSubtrees hostEval.options [
|
||||||
|
[ "hyperhive" ]
|
||||||
|
[
|
||||||
|
"services"
|
||||||
|
"hive-c0re"
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
agentOptions = pickSubtrees agentEval.options [
|
||||||
|
[ "hyperhive" ]
|
||||||
|
];
|
||||||
|
|
||||||
|
hostDoc = pkgs.nixosOptionsDoc {
|
||||||
|
options = hostOptions;
|
||||||
|
inherit transformOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
agentDoc = pkgs.nixosOptionsDoc {
|
||||||
|
options = agentOptions;
|
||||||
|
inherit transformOptions;
|
||||||
|
};
|
||||||
|
|
||||||
|
mkPage =
|
||||||
|
name: title: doc:
|
||||||
|
pkgs.runCommand "hyperhive-${name}-options.md" { } ''
|
||||||
|
{
|
||||||
|
echo "# ${title}"
|
||||||
|
echo
|
||||||
|
echo "<!-- Auto-generated from the hyperhive flake."
|
||||||
|
echo " Source: nix/docs.nix · regenerate with"
|
||||||
|
echo " \`nix build .#${name}\` -->"
|
||||||
|
echo
|
||||||
|
cat ${doc.optionsCommonMark}
|
||||||
|
} > $out
|
||||||
|
'';
|
||||||
|
in
|
||||||
|
{
|
||||||
|
host = mkPage "docs-host" "hyperhive — host options" hostDoc;
|
||||||
|
agent = mkPage "docs-agent" "hyperhive — per-agent options" agentDoc;
|
||||||
|
|
||||||
|
# Bundle both pages plus a thin index so the whole thing can be
|
||||||
|
# published as a single static tree.
|
||||||
|
bundle = pkgs.runCommand "hyperhive-options-docs" { } ''
|
||||||
|
mkdir -p $out
|
||||||
|
cp ${mkPage "docs-host" "hyperhive — host options" hostDoc} $out/host.md
|
||||||
|
cp ${mkPage "docs-agent" "hyperhive — per-agent options" agentDoc} $out/agent.md
|
||||||
|
cat > $out/README.md <<'EOF'
|
||||||
|
# hyperhive — nix options reference
|
||||||
|
|
||||||
|
auto-generated from the hyperhive flake.
|
||||||
|
|
||||||
|
- [host.md](./host.md) — options exposed by `hyperhive.nixosModules.default`
|
||||||
|
to operator host configurations (`services.hive-c0re.*`,
|
||||||
|
`hyperhive.domain`, `hyperhive.forge.*`, `hyperhive.matrix.*`).
|
||||||
|
- [agent.md](./agent.md) — per-agent options declared in
|
||||||
|
`nix/templates/harness-base.nix` and visible from every `agent.nix`
|
||||||
|
(`hyperhive.model`, `hyperhive.allowedRecipients`,
|
||||||
|
`hyperhive.extraMcpServers`, `hyperhive.frontend.*`,
|
||||||
|
`hyperhive.forge.*`, `hyperhive.matrix.*`, `hyperhive.gui.*`).
|
||||||
|
|
||||||
|
regenerate:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
nix build .#docs # bundled tree
|
||||||
|
nix build .#docs-host # host page only
|
||||||
|
nix build .#docs-agent # agent page only
|
||||||
|
```
|
||||||
|
EOF
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue