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,
|
||||
...
|
||||
}:
|
||||
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
|
||||
# are run as a separate check (`checks.cargo-test`) that
|
||||
|
|
@ -167,6 +174,15 @@
|
|||
# host would only succeed via a remote x86 builder.
|
||||
agent-base-toplevel = self.nixosConfigurations.agent-base.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";
|
||||
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