generated from coulomb/repo-seed
This seems to be our first runnable version on railiance01
Some checks failed
Build and Deploy / build-push-deploy (push) Has been cancelled
Some checks failed
Build and Deploy / build-push-deploy (push) Has been cancelled
This commit is contained in:
1
.claude/scheduled_tasks.lock
Normal file
1
.claude/scheduled_tasks.lock
Normal file
@@ -0,0 +1 @@
|
||||
{"sessionId":"7a72372c-e488-456c-baba-1e60d38649cf","pid":9468,"procStart":"127351","acquiredAt":1777404376811}
|
||||
426
HaskellVibePrimer.md
Normal file
426
HaskellVibePrimer.md
Normal file
@@ -0,0 +1,426 @@
|
||||
# Haskell Vibe Primer
|
||||
## Hard-won lessons for coding agents working on inter-hub and IHP projects
|
||||
|
||||
---
|
||||
|
||||
## Quick orientation
|
||||
|
||||
Inter-hub is an IHP (Integrated Haskell Platform) v1.5 application on GHC 9.10.3, managed via Nix/devenv. It has two distinct compilation modes with fundamentally different behaviour:
|
||||
|
||||
| Mode | Command | Compiler | Output | Crashes? |
|
||||
|------|---------|----------|--------|----------|
|
||||
| Dev | `devenv up` → ghcid | GHCi byte-code | In-memory | No (byte-code avoids static linker) |
|
||||
| Production | `nix build .#docker` | Native (cabal) | OCI image | Yes, if archive bug present |
|
||||
|
||||
A build that works in `devenv up` does **not** guarantee `nix build .#docker` will succeed. The production build hits code paths that ghcid never reaches.
|
||||
|
||||
The build host for production is **haskelseed** (192.168.178.135, root/hcs26!x), not CoulombCore. Do not try to run `nix build` on CoulombCore.
|
||||
|
||||
---
|
||||
|
||||
## Part 1 — Known GHC 9.10.3 bugs in this project
|
||||
|
||||
### Bug 1: `module M` re-export causes `.hi` overflow (FIXED in flake.nix)
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
Data.Binary.Get.runGet at position ~287000000: not enough bytes
|
||||
```
|
||||
Crash occurs while GHC reads a `.hi` (interface) file.
|
||||
|
||||
**Cause:** IHP generates a hub module `Generated/ActualTypes.hs` that originally used:
|
||||
```haskell
|
||||
module Generated.ActualTypes
|
||||
( module Generated.Foo
|
||||
, module Generated.Bar
|
||||
... -- 61 sub-modules
|
||||
) where
|
||||
import Generated.Foo
|
||||
import Generated.Bar
|
||||
```
|
||||
|
||||
The `module M` re-export syntax causes GHC to **embed the full exported interface of every sub-module verbatim** into `ActualTypes.hi`. With 61 sub-modules and thousands of typeclass instances, the resulting `.hi` reaches ~287 MB — exceeding GHC 9.10.3's `Data.Binary.Get` 274 MB deserialization limit.
|
||||
|
||||
**Fix (active in `flake.nix`):** The `inter-hub-models` postUnpack overlay rewrites the export list to explicit `T(..)` per-type exports:
|
||||
```haskell
|
||||
module Generated.ActualTypes
|
||||
( Foo(..)
|
||||
, FooId(..)
|
||||
, Bar(..)
|
||||
, ...
|
||||
) where
|
||||
```
|
||||
Explicit re-exports store only compact name-references in `.hi` (not embedded sub-interfaces). `ActualTypes.hi` drops from ~287 MB to ~51 KB.
|
||||
|
||||
**Rule: NEVER use `module M` re-export syntax for generated hub modules with many sub-modules.** Always use explicit `T(..)` exports.
|
||||
|
||||
```haskell
|
||||
-- BAD: embeds sub-interfaces into hub .hi
|
||||
module MyHub (module Sub1, module Sub2) where
|
||||
|
||||
-- GOOD: stores compact references
|
||||
module MyHub (Foo(..), Bar, baz) where
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Bug 2: Truncated `libHSghc-9.10.3-5702.a` in Nix store (FIXED on haskelseed)
|
||||
|
||||
**Symptom:**
|
||||
```
|
||||
panic! (the 'impossible' happened)
|
||||
GHC version 9.10.3:
|
||||
Data.Binary.Get.runGet at position 287686318: not enough bytes
|
||||
```
|
||||
Crash occurs **after** `[477 of 477] Compiling Generated.WidgetVersionInclude` — all modules compiled, crash in post-compilation step.
|
||||
|
||||
**Cause:** The Nix-provisioned static archive for the GHC compiler-as-library is truncated:
|
||||
- Truncated: `ffg3yf2.../lib/.../ghc-9.10.3-5702/libHSghc-9.10.3-5702.a` — 287,768,576 bytes
|
||||
- Full archive: `ffg3yf2.../ghc-9.10.3-partial/lib/.../ghc-9.10.3-5702/libHSghc-9.10.3-5702.a` — 289,295,782 bytes
|
||||
|
||||
The last AR entry (`Expr.o`) claims 517,544 bytes but only 82,258 are present. GHC's `readAr` (via `Data.Binary.Get.runGet`) panics when it tries to read the full entry.
|
||||
|
||||
Why GHC reads this archive at all: The global `ghc-with-packages` package db is searched during the build (cabal configure does not pass `--package-db=clear`). That db registers the `ghc` compiler-as-library package with `library-dirs` pointing to the directory containing the truncated archive symlink. GHC loads this archive during internal post-compilation processing — even when the package has **no Template Haskell**.
|
||||
|
||||
**What does NOT fix it:**
|
||||
- `-fomit-interface-pragmas` — reduces `.hi` size, unrelated to archive loading
|
||||
- `--disable-shared` — affects output type, not input archive reading
|
||||
- `-fexternal-interpreter -pgmi ghc-iserv-dyn` — routes TH to external process, but inter-hub-models has **zero TH**; the archive read is from a different code path
|
||||
|
||||
**Fix applied on haskelseed (2026-05-02):**
|
||||
```bash
|
||||
TRUNCATED="/nix/store/ffg3yf2ypnbz3hc31y7nglrkihz0if01-ghc-9.10.3/lib/ghc-9.10.3/lib/x86_64-linux-ghc-9.10.3/ghc-9.10.3-5702/libHSghc-9.10.3-5702.a"
|
||||
FULL="/nix/store/ffg3yf2ypnbz3hc31y7nglrkihz0if01-ghc-9.10.3/ghc-9.10.3-partial/lib/ghc-9.10.3/lib/x86_64-linux-ghc-9.10.3/ghc-9.10.3-5702/libHSghc-9.10.3-5702.a"
|
||||
chmod u+w "$(dirname "$TRUNCATED")"
|
||||
cp "$FULL" "$TRUNCATED"
|
||||
chmod a-w "$TRUNCATED" "$(dirname "$TRUNCATED")"
|
||||
```
|
||||
|
||||
**If the fix is lost** (flake lock update changing GHC version):
|
||||
```bash
|
||||
# Check archive size before building — should be ~289 MB
|
||||
wc -c /nix/store/HASH-ghc-9.10.3/lib/ghc-9.10.3/lib/x86_64-linux-ghc-9.10.3/ghc-9.10.3-5702/libHSghc-9.10.3-5702.a
|
||||
# If ~287 MB, look for ghc-9.10.3-partial/ in same store path and apply patch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Bug 3: `--disable-shared` causes missing `.dyn_hi` files (FIXED in flake.nix)
|
||||
|
||||
If `inter-hub-models` is built with `--disable-shared`, it produces only `.hi` files but no `.dyn_hi` (dynamic interface files). The dependent `inter-hub-lib` package (built with `--enable-shared` by default in NixPkgs) requires `.dyn_hi` from its dependencies and fails with:
|
||||
```
|
||||
Failed to load dynamic interface file for Generated.Foo:
|
||||
.../Generated/Foo.dyn_hi: does not exist
|
||||
```
|
||||
|
||||
Do not add `--disable-shared` to the inter-hub-models configureFlags unless you also suppress `--enable-shared` in inter-hub-lib (and its transitive dependents). The archive fix (Bug 2) is the correct solution; `--disable-shared` was a failed hypothesis.
|
||||
|
||||
---
|
||||
|
||||
## Part 2 — IHP compilation architecture
|
||||
|
||||
### Compilation layers (from CLAUDE.md)
|
||||
|
||||
```
|
||||
Layer 1 — stable core (compile once, expensive to change):
|
||||
build/Generated/Types.hs IHP auto-generated from Schema.sql
|
||||
Web/Types.hs controller/action type definitions
|
||||
|
||||
Layer 2 — helpers (only touch if Layer 1 is clean):
|
||||
Application/Helper/*.hs 12 helper modules
|
||||
|
||||
Layer 3 — working surface (most errors live here):
|
||||
Web/Controller/*.hs 59 controllers
|
||||
Web/View/**/*.hs 120 views
|
||||
|
||||
Layer 4 — wiring (fix last):
|
||||
Web/FrontController.hs
|
||||
Web/Routes.hs
|
||||
```
|
||||
|
||||
**Fix errors bottom-up, one module at a time.** Never touch Layer 1 during an error-fix loop. A single change to `Web/Types.hs` invalidates all 59 controllers and 120 views simultaneously — equivalent to a full rebuild.
|
||||
|
||||
### Package split
|
||||
|
||||
The project compiles as two separate Cabal packages:
|
||||
|
||||
| Package | Source | Contains |
|
||||
|---------|--------|----------|
|
||||
| `inter-hub-models` | `inter-hub-models-src/build/Generated/` | All IHP-generated types, ~477 modules |
|
||||
| `inter-hub-lib` | `inter-hub-lib-src/` | Application code: `Application/`, `Config/`, `Web/` |
|
||||
|
||||
Critical: **`inter-hub-lib-src` has no `build/` directory.** Generated modules come from the `inter-hub-models` package, not from the lib source tree. Any script that assumes lib-src contains `build/Generated/` will fail. To access generated file content from within inter-hub-lib's build scripts, find inter-hub-models-src dynamically:
|
||||
```bash
|
||||
_models_src=$(find /nix/store -maxdepth 1 -name "*-inter-hub-models-src" ! -name "*.drv" | head -1)
|
||||
```
|
||||
|
||||
### Generated code — what changes when schema changes
|
||||
|
||||
When `Application/Schema.sql` changes and you regenerate via the IHP IDE:
|
||||
- `build/Generated/Types.hs` — one-liner re-export hub (regenerated, do not edit)
|
||||
- `build/Generated/ActualTypes.hs` — type hub (regenerated, patched by postUnpack overlay)
|
||||
- `build/Generated/Foo.hs` — one per table, data type + instances
|
||||
- `build/Generated/FooInclude.hs` — `type instance Include` for eager loading
|
||||
- `build/Generated/ActualTypes/Foo.hs` — sub-module used by ActualTypes hub
|
||||
|
||||
After any schema change, check whether the postUnpack in `flake.nix` still correctly rewrites `Generated.ActualTypes` — run `nix build --keep-failed` and inspect the rewritten file.
|
||||
|
||||
---
|
||||
|
||||
## Part 3 — Nix/devenv specifics
|
||||
|
||||
### How the Nix overlay works
|
||||
|
||||
The `flake.nix` has an `overlays = lib.mkAfter [...]` block in `devenv.shells.default` that overrides the Haskell package set. It intercepts derivations by `pname`:
|
||||
|
||||
```nix
|
||||
mkDerivation = args:
|
||||
let drv = hprev.mkDerivation args;
|
||||
in if (args.pname or "") == "inter-hub-models"
|
||||
then drv.overrideAttrs (old: { ... })
|
||||
else if (args.pname or "") == "inter-hub-lib"
|
||||
then drv.overrideAttrs (old: { ... })
|
||||
else drv;
|
||||
```
|
||||
|
||||
`postUnpack` runs after the source is unpacked but before configure. `postConfigure` runs after `setup configure`. Both run inside the Nix sandbox.
|
||||
|
||||
### Environment variables in Nix builds
|
||||
|
||||
- `$sourceRoot` — relative path to unpacked source (e.g., `inter-hub-models-src`)
|
||||
- `$TMPDIR` — build-specific temp directory (e.g., `/nix/var/nix/builds/nix-PID-RND/`)
|
||||
- `$NIX_BUILD_CORES` — parallelism (8 on haskelseed); NixPkgs Haskell builder passes `--ghc-option=-j$NIX_BUILD_CORES` by default
|
||||
- `$NIX_BUILD_TOP` — may not be set; prefer `$TMPDIR`
|
||||
|
||||
### Configure flags ordering matters
|
||||
|
||||
NixPkgs Haskell builder prepends its own configureFlags before yours. Your overlay's flags are **appended** via `(old.configureFlags or []) ++ [ your-flags ]`. For boolean flags (`--enable-X` / `--disable-X`), the last one wins. For `--ghc-option=-jN`, all are passed and GHC uses the last one.
|
||||
|
||||
Example of NixPkgs flags you must know about:
|
||||
```
|
||||
--enable-shared
|
||||
--enable-split-sections
|
||||
--ghc-option=-j8 (from NIX_BUILD_CORES)
|
||||
```
|
||||
|
||||
To override: append `--disable-shared`, `--disable-split-sections`, `--ghc-option=-j1` in your configureFlags. But beware: disabling shared breaks `.dyn_hi` for downstream packages.
|
||||
|
||||
### The `ghc-with-packages` symlink chain
|
||||
|
||||
The GHC wrapper used in builds (`ghc-with-packages`) exposes packages from both the wrapped GHC derivation and registered Haskell packages. Its `lib/` directory contains symlinks back into the unwrapped GHC derivation. When patching Nix store archives, verify the symlink chain resolves correctly:
|
||||
```bash
|
||||
readlink -f /nix/store/WRAP-ghc-9.10.3-with-packages/lib/.../libHSghc.a
|
||||
wc -c /nix/store/WRAP-ghc-9.10.3-with-packages/lib/.../libHSghc.a
|
||||
```
|
||||
|
||||
### Diagnosing `nix build` failures efficiently
|
||||
|
||||
```bash
|
||||
# Get full build log for a specific derivation
|
||||
nix log /nix/store/HASH-inter-hub-models-0.1.0.drv
|
||||
|
||||
# What derivations would be built (dry run)
|
||||
nix build .#docker --dry-run
|
||||
|
||||
# Keep failed build artifacts for inspection
|
||||
nix build .#docker --keep-failed
|
||||
|
||||
# Check if a store path exists (was the drv already built?)
|
||||
ls /nix/store/EXPECTED-OUTPUT-HASH 2>/dev/null && echo "cached" || echo "not built"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Part 4 — Haskell type system patterns
|
||||
|
||||
### Interface files (`.hi` and `.dyn_hi`)
|
||||
|
||||
GHC produces two kinds of interface files:
|
||||
- `.hi` — static interface, for non-shared compilations
|
||||
- `.dyn_hi` — dynamic interface, required when compiling with `--enable-shared` / `-dynamic-too`
|
||||
|
||||
A package compiled with `--disable-shared` produces `.hi` only. Any package depending on it that was compiled with `--enable-shared` will fail to load the `.dyn_hi`. Always maintain consistent shared/static settings across a package dependency chain.
|
||||
|
||||
### Type families vs Template Haskell
|
||||
|
||||
`type instance` declarations (like `Include "widgetId" ...`) are **type-level computations processed entirely by GHC during type-checking**. They are NOT Template Haskell, do NOT require the TH runtime, and do NOT trigger archive loading via the internal linker.
|
||||
|
||||
Template Haskell requires the TH evaluator (internal or external interpreter) only for modules with:
|
||||
- `{-# LANGUAGE TemplateHaskell #-}` pragma
|
||||
- Splice expressions `$(...)` or quasi-quotes `[| ... |]`
|
||||
- `deriveGeneric`, `makeLenses`, etc. (lens/generics libraries)
|
||||
|
||||
If a module has none of these, `-fexternal-interpreter` has no meaningful effect on it.
|
||||
|
||||
### `module M` re-export vs explicit exports
|
||||
|
||||
```haskell
|
||||
-- EMBEDS sub-interface into .hi (dangerous for large hubs):
|
||||
module Hub (module Sub) where
|
||||
import Sub
|
||||
|
||||
-- Stores compact name-reference in .hi (correct for large hubs):
|
||||
module Hub (Foo(..), Bar, baz) where
|
||||
import Sub (Foo(..), Bar, baz)
|
||||
```
|
||||
|
||||
The `module M` form is fine for small modules (< 10 re-exported sub-modules with modest interfaces). It becomes a GHC 9.10.3 bomb for generated hubs with 50+ sub-modules full of typeclass instances.
|
||||
|
||||
### AR archive format and `readAr`
|
||||
|
||||
GHC's internal static linker uses `Data.Binary.Get.runGet` to read AR archives (`.a` files). Unlike `ar t` (which only reads headers), `readAr` reads **all entry content**. A truncated archive that passes `ar t` will still panic `readAr`. If you see:
|
||||
|
||||
```
|
||||
panic! (the 'impossible' happened)
|
||||
Data.Binary.Get.runGet at position N: not enough bytes
|
||||
```
|
||||
|
||||
Run `ar tv /path/to/suspect.a | tail -5` — if the last entry shows a size, check whether `wc -c /path/to/suspect.a` is substantially smaller than expected.
|
||||
|
||||
---
|
||||
|
||||
## Part 5 — Build compile tools and discipline
|
||||
|
||||
### Compile check scripts
|
||||
|
||||
Inside `devenv shell`:
|
||||
```bash
|
||||
scripts/compile-check # full build via ghcid (all layers), errors → /tmp/ihub-compile-errors.txt
|
||||
scripts/compile-check --bg # background-friendly (no colour/title escape codes)
|
||||
scripts/compile-check-core # Layer 1+2 only — verify clean base
|
||||
```
|
||||
|
||||
### Error-fix discipline
|
||||
|
||||
1. Fix **bottom-up**: Layer 1 → 2 → 3 → 4
|
||||
2. Fix **one module at a time** — wait for ghcid to reload before touching the next module
|
||||
3. **Never change Layer 1 (Web/Types.hs, Generated/Types.hs) while debugging Layer 3 errors** — it restarts the entire recompile
|
||||
4. `Generated/Types.hs` is auto-generated from `Application/Schema.sql`. Edit the schema in IHP IDE, not the generated file
|
||||
|
||||
### Reading GHC error messages
|
||||
|
||||
GHC errors reference **source locations**, not compiled output. When you see:
|
||||
```
|
||||
Web/Controller/Foo.hs:42:5: error:
|
||||
• Couldn't match expected type 'UUID' with actual type 'Text'
|
||||
```
|
||||
|
||||
The fix is in `Web/Controller/Foo.hs:42`, not in any generated file.
|
||||
|
||||
When you see:
|
||||
```
|
||||
Failed to load interface for 'Generated.Foo'
|
||||
```
|
||||
Check that `Generated.Foo` is in the `inter-hub-models` package and that models compiled successfully first.
|
||||
|
||||
### Parallel compilation flag (`-j`)
|
||||
|
||||
GHC's `-j` flag controls **parallel module compilation** within a single package. On haskelseed (2 CPU, ~3.8 GiB RAM), NixPkgs sets `-j8` (from `NIX_BUILD_CORES=8`). The overlay overrides to `-j1` for the models package to prevent OOM on the constrained host. Do not increase this without verifying available memory:
|
||||
```bash
|
||||
free -m # on haskelseed
|
||||
```
|
||||
|
||||
The env var `GHCRTS = "-A32m -M2g"` caps the GHC heap at 2 GiB and sets minor GC allocation to 32 MB. These are set in `devenv.shells.default.env`.
|
||||
|
||||
---
|
||||
|
||||
## Part 6 — Guardrails: expensive mistakes to avoid
|
||||
|
||||
### NEVER do these
|
||||
|
||||
| Action | Why it's expensive |
|
||||
|--------|-------------------|
|
||||
| Edit `build/Generated/Types.hs` directly | Regenerated on next schema sync; change is lost. Also, editing it changes Layer 1 and invalidates all 477 modules |
|
||||
| Add `module M` re-export syntax to a new generated hub module | Embeds sub-interfaces → `.hi` overflow → GHC crash |
|
||||
| Change `Web/Types.hs` or `Web/Types.hs` during a Layer 3 error loop | Restarts compile of all 59 controllers + 120 views |
|
||||
| Add `--disable-shared` to models without removing it from lib | Missing `.dyn_hi` crash in every downstream package |
|
||||
| Hardcode Nix store hashes in postUnpack scripts | Hash changes with every schema change; use `find /nix/store` instead |
|
||||
| Run `nix build .#docker` on CoulombCore | Insufficient RAM (< 4 GiB), will OOM during GHC compilation |
|
||||
| Trust `ar t` to validate an archive | `ar t` reads only headers; GHC reads content. Use `wc -c` and compare to expected size |
|
||||
| Assume `devenv up` success = `nix build` success | Different compilation modes; static linker issues only surface in `nix build` |
|
||||
|
||||
### Before modifying `flake.nix` overlays
|
||||
|
||||
1. **Check what derivation hash the current flake produces**: `nix build .#docker --dry-run`
|
||||
2. **Understand layer dependencies**: changing inter-hub-models configureFlags invalidates models AND all downstream (lib, binaries, docker image)
|
||||
3. **Test postUnpack scripts locally first**: simulate with `bash -n yourscript.sh` and run `awk` commands against sample files
|
||||
4. **Verify `.dyn_hi` will be produced** if `--enable-shared` is set (which is the NixPkgs default)
|
||||
|
||||
### Diagnosing a new crash before trying fixes
|
||||
|
||||
1. Get the full log: `nix log /nix/store/HASH-inter-hub-models-0.1.0.drv`
|
||||
2. Find the crash position: `Data.Binary.Get.runGet at position N`
|
||||
3. Determine which file is being read at that position (check file sizes of `.hi`, `.a`, `.conf` etc.)
|
||||
4. Check `ar tv suspect.a | tail -5` to see if the last AR entry header is valid
|
||||
5. Only then propose a fix — flag-based fixes almost never work for archive truncation issues
|
||||
|
||||
---
|
||||
|
||||
## Part 7 — IHP-specific Haskell patterns
|
||||
|
||||
### IHP record access
|
||||
|
||||
IHP generates `HasField` instances. Access fields with:
|
||||
```haskell
|
||||
record.fieldName -- accessor (uses OverloadedRecordDot or get)
|
||||
record |> set #fieldName value -- functional update
|
||||
```
|
||||
|
||||
### IHP type family: `Include`
|
||||
|
||||
```haskell
|
||||
-- Generated/WidgetVersionInclude.hs (typical):
|
||||
type instance Include "widgetId" (WidgetVersion' widgetId) =
|
||||
WidgetVersion' (GetModelById widgetId)
|
||||
```
|
||||
|
||||
This is pure type-level. `Include` is a closed type family that fills in the concrete type for an association when you do eager loading with `fetchRelated`. It is NOT Template Haskell.
|
||||
|
||||
### IHP controller pattern
|
||||
|
||||
```haskell
|
||||
-- Each action is a function returning an IO Response (via implicit context)
|
||||
action ShowWidgetAction { widgetId } = do
|
||||
widget <- fetch widgetId
|
||||
render ShowView { .. }
|
||||
```
|
||||
|
||||
Controller type errors almost always mean a mismatch in `Web/Types.hs` — the action type declared there must match the implementation.
|
||||
|
||||
### Schema → Generated code cycle
|
||||
|
||||
```
|
||||
Edit Application/Schema.sql
|
||||
→ IHP IDE at localhost:8001 generates build/Generated/
|
||||
→ Regenerated: Types.hs, ActualTypes.hs, Foo.hs, FooInclude.hs
|
||||
→ Also regenerates Web/Types.hs (action types) and Web/Routes.hs
|
||||
→ Run compile-check to verify
|
||||
```
|
||||
|
||||
After schema changes, always verify the postUnpack overlay in `flake.nix` still produces valid Haskell. The `_types` / `_exports` awk scripts in postUnpack depend on the generated file structure remaining stable.
|
||||
|
||||
---
|
||||
|
||||
## Quick reference card
|
||||
|
||||
```
|
||||
# Build status checks (on haskelseed)
|
||||
nix build .#docker --dry-run # what would be built?
|
||||
nix log /nix/store/HASH-inter-hub-models-0.1.0.drv # full build log
|
||||
wc -c /nix/store/ffg3yf2.../libHSghc-9.10.3-5702.a # verify archive size (must be ~289 MB)
|
||||
|
||||
# If archive is truncated (287 MB), apply patch:
|
||||
# Full archive is at same derivation's ghc-9.10.3-partial/ subdirectory
|
||||
# See project_ghc_build_fix.md in Claude memory for exact commands
|
||||
|
||||
# Compilation layers (in devenv shell)
|
||||
scripts/compile-check-core # Layer 1+2 only
|
||||
scripts/compile-check # Full build, errors → /tmp/ihub-compile-errors.txt
|
||||
|
||||
# Schema regeneration
|
||||
# Use IHP IDE at localhost:8001, then run compile-check
|
||||
|
||||
# Production build → push → deploy
|
||||
nix build .#docker
|
||||
skopeo copy docker-archive:result docker://92.205.130.254:32166/coulomb/inter-hub:$(git rev-parse --short HEAD)
|
||||
```
|
||||
Reference in New Issue
Block a user