claude-forgejo-sandbox/flake.nix
Padreug df0fd9a9ba feat: extract reforge engine into a standalone consumable flake
The forgejo-sandbox / reforge harness, lifted out of the machine config
into a host-agnostic, generic engine anyone can consume with Nix.

Two layers:
- engine (this repo) — nixosModules.reforge stands up the sandbox forge,
  provisions role accounts + tokens, enforces branch protection, and puts
  the reforge-* CLI + forgejo-mcp on PATH. Carries no project specifics.
- run config — per-project manifest/charter/agenda/issues an adopter fills
  in; scaffold one with the `reforge` flake template.

Portability fixes vs the in-config version:
- forgejo-mcp resolved from $REFORGE_MCP_BIN or PATH, never a named host
  (kills the nixosConfigurations.omni hardcode).
- all instance data + paths parameterized via REFORGE_* env, baked into the
  reforge-scripts wrappers from module options (configDir, agentsDir,
  refsDir, org, port, tokenOwner, ...).
- option namespace neutral (reforge.* not omni.packs.*); settings policies
  carry no absolute /etc/nixos paths.
- role briefs + orchestrator playbook genericized: all project specifics
  point at the charter; refs corpus optional.

Validated: nix flake check (eval) + builds of forgejo-mcp, reforge-scripts,
and a module-eval check.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-18 22:51:47 +02:00

126 lines
4.8 KiB
Nix

{
description = "reforge a local Forgejo sandbox that runs a role-isolated agent team to rebuild a software stack from pinned bases to a declared target, coordinating entirely through the forge (issues, PRs, gated review).";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
};
outputs =
{ self, nixpkgs }:
let
systems = [
"x86_64-linux"
"aarch64-linux"
];
forAllSystems = f: nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system});
appNames = [
"reforge-seed"
"reforge-reset"
"reforge-compare"
"reforge-smoke"
"reforge-kickoff"
"reforge-role"
"reforge-orchestrator"
"reforge-fetch-targets"
];
in
{
# The NixOS module. Import it, set `reforge.enable = true` and
# `reforge.configDir`, rebuild — you get the sandbox forge, the
# provisioned role accounts + tokens, and the reforge-* CLI on PATH.
# See docs/architecture.md.
nixosModules.reforge = import ./modules/reforge.nix;
nixosModules.default = self.nixosModules.reforge;
# Fill-in-the-blank run config: `nix flake init -t <this>#reforge`
# drops a manifest/charter/agenda/issues scaffold plus a consumer
# flake.nix that wires this engine in. Edit the four data files and
# you have your own run.
templates.reforge = {
path = ./templates/reforge;
description = "A reforge run: manifest + charter + agenda stubs and a consumer flake wiring the engine as a NixOS module.";
};
templates.default = self.templates.reforge;
packages = forAllSystems (pkgs: {
forgejo-mcp = pkgs.callPackage ./packages/forgejo-mcp.nix { };
# Standalone build of the CLI, with sandbox defaults and the
# bundled template as the config dir — enough for `nix run` to work
# against a manually-run forge. On NixOS the module builds its own
# copy with your host's real defaults baked in.
reforge-scripts = pkgs.callPackage ./packages/reforge-scripts.nix {
forgejoMcp = pkgs.callPackage ./packages/forgejo-mcp.nix { };
forgeUrl = "http://localhost:3030";
org = "sandbox-team";
adminUser = "sandbox-admin";
tokensDir = "/var/lib/forgejo-sandbox/tokens";
stateDir = "/var/lib/forgejo-sandbox";
configDir = ./templates/reforge;
};
default = self.packages.${pkgs.system}.reforge-scripts;
});
# `nix run <this>#reforge-seed`, etc.
apps = forAllSystems (
pkgs:
nixpkgs.lib.genAttrs appNames (name: {
type = "app";
program = "${self.packages.${pkgs.system}.reforge-scripts}/bin/${name}";
})
);
checks = forAllSystems (
pkgs:
{
# Package derivations build (validates the wrapper + that agents/
# and settings/ are present and shipped).
forgejo-mcp = self.packages.${pkgs.system}.forgejo-mcp;
reforge-scripts = self.packages.${pkgs.system}.reforge-scripts;
}
// nixpkgs.lib.optionalAttrs (pkgs.stdenv.hostPlatform.isLinux) {
# Lightweight module-eval check: evaluate a NixOS system that
# imports the module with enable=true, then build only (a) the
# provisioning script the systemd unit runs and (b) the
# reforge-scripts CLI as the module wires it (with cfg.configDir
# etc. baked in). This forces the module's options, assertions,
# and both derivations to evaluate without building a full system
# toplevel.
module-eval =
let
sys = nixpkgs.lib.nixosSystem {
system = pkgs.system;
modules = [
self.nixosModules.reforge
{
boot.loader.grub.enable = false;
fileSystems."/" = {
device = "nodev";
fsType = "ext4";
};
system.stateVersion = "24.11";
reforge.enable = true;
reforge.configDir = ./templates/reforge;
}
];
};
execStart = sys.config.systemd.services.reforge-provision.serviceConfig.ExecStart;
cliFromModule = builtins.filter (
p: (p.pname or "") == "reforge-scripts"
) sys.config.environment.systemPackages;
in
pkgs.runCommand "reforge-module-eval" { } (
''
mkdir -p "$out"
ln -sn ${execStart} "$out/provision-script"
''
+ nixpkgs.lib.concatMapStrings (p: ''ln -sn ${p} "$out/cli"'' + "\n") cliFromModule
);
}
);
formatter = forAllSystems (pkgs: pkgs.nixfmt-rfc-style);
};
}