Files
inter-hub/flake.nix
tegwick 3664af59f2
Some checks failed
Build and Deploy / build-push-deploy (push) Has been cancelled
chore(debug): add -ddump-if-trace to inter-hub-models to diagnose GHC crash
All 477 modules compile successfully but GHC panics at position 287,686,318
during finalization. Trace will show which .hi file is being read at crash time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-01 23:27:21 +02:00

231 lines
14 KiB
Nix

{
inputs = {
ihp.url = "github:digitallyinduced/ihp/v1.5";
nixpkgs.follows = "ihp/nixpkgs";
nixpkgs-nixos.follows = "ihp/nixpkgs-nixos";
flake-parts.follows = "ihp/flake-parts";
devenv.follows = "ihp/devenv";
systems.follows = "ihp/systems";
devenv-root = {
url = "file+file:///dev/null";
flake = false;
};
};
outputs = inputs@{ self, nixpkgs, nixpkgs-nixos, ihp, flake-parts, systems, ... }:
flake-parts.lib.mkFlake { inherit inputs; } {
systems = import systems;
imports = [ ihp.flakeModules.default ];
perSystem = { pkgs, config, lib, ... }: {
ihp = {
appName = "inter-hub";
enable = true;
projectPath = ./.;
packages = with pkgs; [
tailwindcss
];
haskellPackages = p: with p; [
# Haskell dependencies go here
p.ihp
base
wai
text
# ihp-mail # Email support: https://ihp.digitallyinduced.com/Guide/mail.html
# ihp-datasync # Real-time DataSync
# ihp-job-dashboard # Job dashboard UI
# ihp-typed-sql # Type-safe SQL queries
# ihp-pglistener # PostgreSQL LISTEN/NOTIFY
# Phase 5: Anthropic API calls
http-conduit
aeson
string-conversions
# Phase 9: External API, crypto, SDK generation
cryptohash-sha256
base16-bytestring
random-bytestring
yaml
network-uri
];
devHaskellPackages = p: with p; [
cabal-install
hlint
hspec
ihp-hspec
];
# Hoogle documentation server — disabled to save ~400 MB on constrained host
withHoogle = false;
# Disable relation type machinery for faster compilation
# relationSupport = false;
# Skip tests/haddock for specific packages to speed up builds
# dontCheckPackages = [ "my-package" ];
# doJailbreakPackages = [ "my-package" ];
# dontHaddockPackages = [ "my-package" ];
# Production build tuning
# optimizationLevel = "2"; # Default: "1", use "2" for more optimized production binaries
# rtsFlags = "-A96m -N"; # GHC runtime flags for compiled binaries
# Mount additional directories under /static/ in production builds
# static.extraDirs = {
# # Frontend = self.packages.${system}.frontend;
# };
# static.makeBundling = true; # Set false if not using Makefile for CSS/JS bundling
};
# OCI container image for Kubernetes deployment (Railiance01).
# Build: nix build .#docker
# Push: skopeo copy docker-archive:result docker://92.205.130.254:32166/coulomb/inter-hub:SHA
# Uses IHP's built-in unoptimized image; binary is /bin/RunProdServer.
packages.docker = config.packages.unoptimized-docker-image;
# Custom configuration that will start with `devenv up`
devenv.shells.default = {
# Start Mailhog on local development to catch outgoing emails
# services.mailhog.enable = true;
# PostgreSQL extensions
# services.postgres.extensions = extensions: [ extensions.postgis ];
# GHC 9.10.3 crash fix: Generated.ActualTypes uses `module M` re-export
# syntax for 61 sub-modules; the resulting ActualTypes.hi exceeds GHC's
# ~274 MB binary-deserialization limit (crash at position 287686318).
#
# pkgs is built from `import nixpkgs { overlays = devenv.shells.default.overlays; }`.
# IHP adds ihp.overlays.default to this list, which sets
# pkgs.ghc = haskellPackages.override { overrides = ihpOverrides }.
# We extend pkgs.ghc with a mkDerivation override (lib.mkAfter ensures
# we run after IHP's overlay, so prev.ghc is already IHP's package set).
# For inter-hub-models: rewrite ActualTypes.hs export list from (module N)
# syntax to explicit T(..) re-exports — keeps hub functional for qualified
# references (Generated.ActualTypes.T) while producing compact .hi.
# Generated.Types stubbed; inter-hub-lib replaces its import with direct
# entity imports (sourceRoot is per-package, originals intact there).
overlays = lib.mkAfter [
(final: prev: {
ghc = prev.ghc.extend (hfinal: hprev: {
mkDerivation = args:
let drv = hprev.mkDerivation args;
in if (args.pname or "") == "inter-hub-models"
then drv.overrideAttrs (old: {
# GHC 9.10.3 crash: `module M` re-export syntax in Generated.ActualTypes
# embeds 61 full sub-interfaces into ActualTypes.hi (~287 MB), exceeding
# GHC's 274 MB binary read limit.
#
# Fix: rewrite the hub's export list from `module M` syntax to explicit
# T(..) re-exports. Explicit re-exports store only name references in
# the .hi file (compact); `module M` embeds the full sub-interface.
# Hub stays functional (consumers still qualify via Generated.ActualTypes),
# but .hi stays small.
configureFlags = (old.configureFlags or []) ++ [
"--ghc-option=-O0"
"--ghc-option=-fomit-interface-pragmas"
"--ghc-option=-ddump-if-trace"
];
postUnpack = (old.postUnpack or "") + ''
_actual="$sourceRoot/build/Generated/ActualTypes.hs"
# Rewrite hub export list: (module N, ...) explicit names.
# IHP pattern: data Foo' params = Foo {...} (primed type, unprimed ctor)
# type Foo = Foo' arg1 arg2 (concrete alias, kind *)
# ADTs: export T(..) to include type + ctor + fields.
# type aliases: export T (no (..) not an ADT).
# type instance lines start with lowercase 'i', so don't match [A-Z].
_types=$(
{
awk '/^data [A-Z]|^newtype [A-Z]/{print $2"(..)"}
/^type [A-Z]/{print $2}' \
"$sourceRoot/build/Generated/Enums.hs"
find "$sourceRoot/build/Generated/ActualTypes" -name "*.hs" | \
sort | while IFS= read -r _m; do
awk '/^data [A-Z]|^newtype [A-Z]/{print $2"(..)"}
/^type [A-Z]/{print $2}' "$_m"
done
} | sort -u
)
_exports=$(echo "$_types" | \
awk 'NR==1{printf " %s", $0; next} {printf "\n , %s", $0} END{printf "\n"}')
_imports=$(awk '/^import Generated\./{print}' "$_actual")
{
printf 'module Generated.ActualTypes\n ( %s ) where\n' "$_exports"
printf '%s\n' "$_imports"
} > "$_actual.new" && mv "$_actual.new" "$_actual"
# Stub Generated.Types (inter-hub-lib reads original from its sourceRoot)
printf '%s\n' 'module Generated.Types () where' \
> "$sourceRoot/build/Generated/Types.hs"
'';
})
else if (args.pname or "") == "inter-hub-lib"
then drv.overrideAttrs (old: {
# Generated.Types is an empty stub in models — hub removed to avoid
# module M re-export crash. Replace every bare `import Generated.Types`
# with direct imports of the 119 individual entity modules.
# Generated.ActualTypes hub is still functional (explicit T(..) exports),
# so no patching needed for ActualTypes imports in this package.
postUnpack = (old.postUnpack or "") + ''
_types="$sourceRoot/build/Generated/Types.hs"
_imp=$(mktemp)
awk '/^import Generated\./{print "import " $2}' "$_types" > "$_imp"
find "$sourceRoot" -name "*.hs" | while IFS= read -r _f; do
if grep -qE "^import Generated\.Types$" "$_f"; then
awk -v imp="$_imp" '
/^import Generated\.Types$/{
while ((getline ln < imp) > 0) print ln
close(imp)
next
}
{ print }' "$_f" > "$_f.new" && mv "$_f.new" "$_f"
fi
done
rm -f "$_imp"
'';
})
else drv;
});
})
];
# Resource limits for constrained host (2 CPU, ~3.8 GiB RAM).
# -A32m: smaller minor heap (reduces GC pressure).
# -M2g: hard heap ceiling (prevents OOM on large compiles).
# Note: -N1 is intentionally omitted — it requires -threaded and
# would break build-generated-code and similar tools.
# GHC parallel module compilation is capped via -j1 in .ghci.
env.GHCRTS = "-A32m -M2g";
# Custom processes that don't appear in https://devenv.sh/reference/options/
processes = {
tailwind.exec = "tailwindcss -c tailwind/tailwind.config.js -i ./tailwind/app.css -o static/app.css --watch=always";
};
};
};
# Adding the new NixOS configuration for "production"
# See https://ihp.digitallyinduced.com/Guide/deployment.html#deploying-with-deploytonixos for more info
# Used to deploy the IHP application
flake.nixosConfigurations."production" = import ./Config/nix/hosts/production/host.nix { inherit inputs; };
};
# The following configuration speeds up build times by using the devenv, cachix and digitallyinduced binary caches
# You can add your own cachix cache here to speed up builds. For that uncomment the following lines and replace `CHANGE-ME` with your cachix cache name
nixConfig = {
extra-substituters = [
"https://devenv.cachix.org"
"https://cachix.cachix.org"
"https://digitallyinduced.cachix.org"
# "https://CHANGE-ME.cachix.org"
];
extra-trusted-public-keys = [
"devenv.cachix.org-1:w1cLUi8dv3hnoSPGAuibQv+f9TZLr6cv/Hm9XgU50cw="
"cachix.cachix.org-1:eWNHQldwUO7G2VkjpnjDbWwy4KQ/HNxht7H4SSoMckM="
"digitallyinduced.cachix.org-1:y+wQvrnxQ+PdEsCt91rmvv39qRCYzEgGQaldK26hCKE="
# "CHANGE-ME.cachix.org-1:CHANGE-ME-PUBLIC-KEY"
];
};
}