build(dev): add pinned Nix and nix-direnv environments

This commit is contained in:
0xrsydn 2026-09-23 18:32:49 +07:00
commit dfa39edfa0
7 changed files with 166 additions and 3 deletions

2
.envrc Normal file
View file

@ -0,0 +1,2 @@
# Requires direnv with nix-direnv enabled in your user configuration.
use flake

5
.gitignore vendored
View file

@ -2,6 +2,11 @@
__pycache__/
*.py[cod]
# Local nix-direnv cache and Nix build links
.direnv/
/result
/result-*
# Machine state from bot runs -- reproducible, not source
deck.json

View file

@ -16,6 +16,9 @@
## Checks
Use Python 3.10+ from the repository root. Core Python code uses the standard library.
Use `direnv allow` with nix-direnv or `nix develop` for the pinned toolchain.
`nix flake check -L` runs the offline checks below in an isolated environment.
See `docs/DEVELOPMENT.md` for setup and platform limits.
```sh
python3 test_facts.py && python3 test_brain.py && python3 test_run.py

69
docs/DEVELOPMENT.md Normal file
View file

@ -0,0 +1,69 @@
# Nix development environment
The repository provides a locked development shell for `x86_64-linux` and
`aarch64-darwin`: the CachyOS desktop and Apple Silicon MacBook. The shell provides Python, .NET SDK 9, Git, Jujutsu, curl, and Bash.
`flake.lock` pins the package source for both desktop and laptop.
## nix-direnv
Enable flakes in Nix and configure direnv plus nix-direnv in your user environment.
The repository does not change your shell configuration. With Home Manager:
```nix
programs.direnv = {
enable = true;
nix-direnv.enable = true;
};
```
Ensure your interactive shell has the direnv hook enabled. Then, in the repository:
```sh
direnv allow
```
The checked-in `.envrc` calls `use flake`. Review it before allowing it.
`.direnv/` is ignored. No credentials are loaded by `.envrc`.
The first activation can download substantial SDK dependencies.
Without direnv:
```sh
nix develop
```
## Offline checks
```sh
nix flake check -L
```
This runs the three Python regression scripts, dataset integrity checks, and Bash
syntax checks. The check uses an isolated home and explicit source inputs. It
needs no game, credentials, model calls, or submodule checkout. It does not rebuild
the dataset. Nix can download dependencies before the offline check starts.
For interactive checks in the shell:
```sh
python3 test_facts.py && python3 test_brain.py && python3 test_run.py
python3 migrate.py --check-only
bash -n eval_batch.sh ab_card_skip.sh
```
The flake does not build or launch the game. Build the mod inside `nix develop`
or the direnv shell, using the local game path described in [MOD_SETUP.md](MOD_SETUP.md).
Proprietary game assemblies remain outside the Nix store. The private mod submodule
requires separate Git/SSH access, but the development shell does not fetch it.
Live bot execution still needs the local mod API and separately configured model
credentials. `--dry-run` can make model calls; it is not an offline test.
## Updating packages
Run `nix flake update nixpkgs`, then repeat the offline checks and mod build.
Review and commit the lock-file update deliberately. Do not update dependencies
merely to enter the shell.
The outputs support the listed systems, but a successful macOS check does not
prove Linux game integration. Run `nix flake check -L` on CachyOS too.

View file

@ -32,7 +32,9 @@ revision changes require Git; ordinary bot changes can continue to use `jj`.
## Build on CachyOS / Linux
Install .NET SDK 9 and the native Linux Steam version of Slay the Spire 2.
Enter the pinned development environment with `direnv allow` (nix-direnv) or
`nix develop`. It includes .NET SDK 9; see [DEVELOPMENT.md](DEVELOPMENT.md).
Install the native Linux Steam version of Slay the Spire 2 separately.
Check that `dotnet --list-sdks` lists a 9.x SDK. Set `GAME_DIR` to the actual Steam
library path; custom libraries and Flatpak Steam use different paths.
@ -45,8 +47,8 @@ dotnet build vendor/STS2MCP/STS2_MCP.csproj -c Release \
-p:STS2GameDir="$GAME_DIR" -o /tmp/sts2-mcp-build
```
If you already use Nix, you can replace `dotnet build` with
`nix shell nixpkgs#dotnet-sdk_9 --command dotnet build`.
Outside the shell, prefix the build command with `nix develop --command`.
This uses the repository lock file rather than your machine's nixpkgs registry.
Build against your installed game assemblies. A successful Mac build does not
prove compatibility with a different Linux game version.

27
flake.lock generated Normal file
View file

@ -0,0 +1,27 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1790046670,
"narHash": "sha256-MYiI+CzL0tuWgRPjGsKCDHqYs2T3OzMlMQWOYWG0qso=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "6774f7bc253789b113a4f39285dc0fa100abeacc",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}

55
flake.nix Normal file
View file

@ -0,0 +1,55 @@
{
description = "STS2 bot development and offline checks";
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { nixpkgs, ... }:
let
systems = [ "x86_64-linux" "aarch64-darwin" ];
forAllSystems = nixpkgs.lib.genAttrs systems;
packagesFor = system: import nixpkgs { inherit system; };
in
{
devShells = forAllSystems (system:
let pkgs = packagesFor system;
in {
default = pkgs.mkShellNoCC {
packages = with pkgs; [ python3 dotnet-sdk_9 git jujutsu curl bash ];
DOTNET_CLI_TELEMETRY_OPTOUT = "1";
DOTNET_NOLOGO = "1";
};
});
checks = forAllSystems (system:
let pkgs = packagesFor system;
in {
offline = pkgs.runCommand "sts2-offline-checks" {
nativeBuildInputs = [ pkgs.python3 pkgs.bash ];
# Explicit inputs exclude credentials, local captures, game binaries,
# and submodules. Only the committed regression fixtures are needed.
source = pkgs.lib.fileset.toSource {
root = ./.;
fileset = pkgs.lib.fileset.unions [
./facts.py ./brain.py ./jev.py ./sts2.py ./run.py
./run_state.py ./recording.py ./migrate.py ./policy
./test_facts.py ./test_brain.py ./test_run.py
./eval_batch.sh ./ab_card_skip.sh
./dataset ./capture/09_now.json
];
};
} ''
export HOME="$TMPDIR/home"
mkdir -p "$HOME"
cp -R "$source" source
chmod -R u+w source
cd source
python3 test_facts.py
python3 test_brain.py
python3 test_run.py
python3 migrate.py --check-only
bash -n eval_batch.sh ab_card_skip.sh
touch "$out"
'';
});
};
}