generated from coulomb/repo-seed
feat(WP-0016): build infrastructure — ghcid standalone script and error-fix loop workplan
- scripts/compile-check: runs ghcid in isolation (no postgres/tailwind) for fast incremental compilation feedback; writes errors to /tmp/ihub-compile-errors.txt - .ghci: add -fkeep-going so GHC reports all module errors in one pass - WP-0016 workplan: documents module dependency layers, error-fix SOP, and autonomous ralph-loop approach for iterative error fixing Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
3
.ghci
3
.ghci
@@ -4,4 +4,7 @@
|
||||
-- Resource limit: override IHP's default -j (unlimited parallel) with -j1
|
||||
-- on this constrained host (2 CPU / 3.8 GiB RAM).
|
||||
:set -j1
|
||||
-- Report errors from all modules in one pass (don't stop at first failure).
|
||||
-- Critical for batch error fixing — see IHUB-WP-0016 C4.
|
||||
:set -fkeep-going
|
||||
import IHP.Prelude
|
||||
44
scripts/compile-check
Executable file
44
scripts/compile-check
Executable file
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
# bin/compile-check — run ghcid standalone for fast compilation feedback.
|
||||
#
|
||||
# Does NOT start postgres or tailwind — just GHC.
|
||||
# Relies on .ghci (sets -j1, loads IHP config).
|
||||
#
|
||||
# Usage:
|
||||
# bin/compile-check # interactive: errors shown in terminal + log
|
||||
# bin/compile-check --bg # log only (for Claude monitoring loop)
|
||||
#
|
||||
# Pre-requisite: run inside `devenv shell` (IHP_LIB must be set).
|
||||
# Or: `devenv shell -- bin/compile-check`
|
||||
#
|
||||
# Log file: /tmp/ihub-compile-errors.txt (override with IHUB_COMPILE_LOG)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
LOGFILE="${IHUB_COMPILE_LOG:-/tmp/ihub-compile-errors.txt}"
|
||||
MODE="${1:-}"
|
||||
|
||||
# Ensure IHP_LIB is available
|
||||
if [[ -z "${IHP_LIB:-}" ]]; then
|
||||
echo "ERROR: IHP_LIB is not set. Run inside devenv shell:" >&2
|
||||
echo " devenv shell -- bin/compile-check" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
: > "$LOGFILE"
|
||||
echo "[compile-check] Log: $LOGFILE"
|
||||
echo "[compile-check] Mode: ${MODE:-interactive}"
|
||||
|
||||
if [[ "$MODE" == "--bg" ]]; then
|
||||
# Background: write to log only, no colour/title
|
||||
exec ghcid \
|
||||
--no-title \
|
||||
--outputfile "$LOGFILE" \
|
||||
--command "ghci"
|
||||
else
|
||||
# Interactive: show errors in terminal AND write to log
|
||||
exec ghcid \
|
||||
--no-title \
|
||||
--outputfile "$LOGFILE" \
|
||||
--command "ghci"
|
||||
fi
|
||||
171
workplans/IHUB-WP-0016-build-infrastructure-and-error-loop.md
Normal file
171
workplans/IHUB-WP-0016-build-infrastructure-and-error-loop.md
Normal file
@@ -0,0 +1,171 @@
|
||||
---
|
||||
id: IHUB-WP-0016
|
||||
type: workplan
|
||||
title: "Build Infrastructure: Incremental Compilation and Autonomous Error-Fix Loop"
|
||||
domain: inter_hub
|
||||
repo: inter-hub
|
||||
status: open
|
||||
owner: custodian
|
||||
topic_slug: inter_hub
|
||||
created: "2026-04-10"
|
||||
updated: "2026-04-10"
|
||||
depends_on: []
|
||||
---
|
||||
|
||||
# IHUB-WP-0016 — Build Infrastructure: Incremental Compilation and Autonomous Error-Fix Loop
|
||||
|
||||
## Goal
|
||||
|
||||
Make GHC compilation fast enough for iterative error fixing without blocking the
|
||||
machine or requiring user involvement. The first full build is unavoidably slow
|
||||
(Nix dep download + all 180+ modules), but subsequent rebuilds must be incremental
|
||||
(seconds per changed file). An autonomous error-fix loop must allow Claude to iterate
|
||||
on compilation errors independently.
|
||||
|
||||
## Background
|
||||
|
||||
### Why compilation is slow
|
||||
|
||||
IHP compiles the entire project as one GHC executable target containing ~180 Haskell
|
||||
modules (Generated types + Web.Types + 12 helpers + 59 controllers + 120 views +
|
||||
FrontController/Routes). GHC compiles modules sequentially (`.ghci` enforces `-j1`
|
||||
for this constrained host) and caches each module's `.o`/`.hi` files. Once a module
|
||||
is compiled and its dependencies have not changed, it is NOT recompiled.
|
||||
|
||||
**First build**: slow — GHC compiles all 180 modules from scratch, plus Nix fetches
|
||||
deps. Unavoidable. Expected: 20–60 min on constrained hardware.
|
||||
|
||||
**Subsequent incremental builds**: fast — only changed modules and their dependents
|
||||
recompile. A single controller change: ~5–30 seconds. This is what we rely on.
|
||||
|
||||
### Module dependency layers (compilation order, bottom-up)
|
||||
|
||||
```
|
||||
Layer 1 (stable core — compile once, never touch during error loops):
|
||||
build/Generated/*.hs IHP auto-generated from Schema.sql
|
||||
Web/Types.hs 500-line controller type definitions
|
||||
|
||||
Layer 2 (helpers — only touch if Layer 1 is clean):
|
||||
Application/Helper/*.hs 12 files
|
||||
Generated/ (IHP code-gen output, if present)
|
||||
|
||||
Layer 3 (working surface — most errors will be here):
|
||||
Web/Controller/*.hs 59 controllers
|
||||
Web/View/**/*.hs 120 views
|
||||
|
||||
Layer 4 (wiring — fix last):
|
||||
Web/FrontController.hs
|
||||
Web/Routes.hs
|
||||
```
|
||||
|
||||
**Rule**: never modify Layer 1 during error-fix loops. Changes to Web/Types.hs or
|
||||
Generated types invalidate all 59 controllers and 120 views simultaneously.
|
||||
|
||||
### Why `devenv up` is overkill for error checking
|
||||
|
||||
`devenv up` starts: PostgreSQL, file-change watcher, Tailwind CSS watcher, AND
|
||||
ghcid. For compilation error fixing we only need ghcid. Running ghcid standalone
|
||||
skips the database startup, port binding, and service orchestration overhead.
|
||||
|
||||
## Tasks
|
||||
|
||||
### C1 — Create `scripts/compile-check` script ✓
|
||||
|
||||
A shell script at `scripts/compile-check` that runs ghcid in isolation (no postgres, no tailwind):
|
||||
|
||||
```bash
|
||||
#!/usr/bin/env bash
|
||||
# scripts/compile-check
|
||||
# Run ghcid standalone for fast compilation feedback.
|
||||
# Outputs errors to stdout AND to /tmp/ihub-compile-errors.txt for monitoring.
|
||||
# Does NOT start postgres or tailwind.
|
||||
#
|
||||
# Usage:
|
||||
# scripts/compile-check # interactive, shows errors in terminal
|
||||
# scripts/compile-check --bg # write to log only (for Claude monitoring)
|
||||
#
|
||||
# Pre-requisite: be inside `devenv shell` or have IHP_LIB set.
|
||||
set -euo pipefail
|
||||
LOGFILE="${IHUB_COMPILE_LOG:-/tmp/ihub-compile-errors.txt}"
|
||||
: > "$LOGFILE" # truncate on start
|
||||
echo "[compile-check] Writing errors to $LOGFILE"
|
||||
exec ghcid \
|
||||
--no-title \
|
||||
--outputfile "$LOGFILE" \
|
||||
--command "ghci"
|
||||
```
|
||||
|
||||
This relies on `.ghci` (already present) which sets up `-j1` and loads the IHP config.
|
||||
|
||||
### C2 — Verify GHC object cache persistence
|
||||
|
||||
GHC stores compiled objects in IHP's `.devenv` or a project-local `dist-newstyle/`
|
||||
equivalent. Verify the cache survives between `devenv up` restarts:
|
||||
|
||||
```bash
|
||||
# After first successful build, check cache location:
|
||||
find /home/tegwick/inter-hub -name "*.o" -newer Main.hs 2>/dev/null | head -5
|
||||
```
|
||||
|
||||
If the cache is cleared on each `devenv up` restart, add `IHP_BUILD_CACHE` or
|
||||
configure the Nix build dir to persist. Document the location here.
|
||||
|
||||
### C3 — Autonomous error-fix loop (ralph-workplan)
|
||||
|
||||
Configure a ralph-workplan loop:
|
||||
1. `scripts/compile-check --bg` runs ghcid in background, writing to `/tmp/ihub-compile-errors.txt`
|
||||
2. Monitor tool watches the log file for new error output
|
||||
3. On error output: read errors → identify failing module → apply fix → ghcid auto-reloads
|
||||
4. On "All good" output: loop exits, reports clean build
|
||||
|
||||
**Loop discipline**:
|
||||
- Fix errors bottom-up (Layer 1 → Layer 2 → Layer 3 → Layer 4)
|
||||
- Fix one module at a time; wait for ghcid reload before fixing the next
|
||||
- Do NOT make speculative changes to stable layers while fixing working-surface errors
|
||||
- Maximum 3 fix attempts per module before escalating to user
|
||||
|
||||
### C4 — Add GHC `-fwrite-interface` and `-keep-going` flags to `.ghci`
|
||||
|
||||
```
|
||||
-- Continue past errors in other modules (report all errors in one pass)
|
||||
:set -fkeep-going
|
||||
-- Ensure interface files are written even on partial success
|
||||
:set -fwrite-interface
|
||||
```
|
||||
|
||||
`-fkeep-going` lets GHC report errors from all modules in one pass rather than
|
||||
stopping at the first failure — critical for batch error fixing.
|
||||
|
||||
### C5 — Document module surface constraints in CLAUDE.md
|
||||
|
||||
Add a "Compilation Layers" section to CLAUDE.md noting:
|
||||
- Never modify Layer 1 during error-fix loops
|
||||
- Each layer's expected compile time after first build
|
||||
- Cache location and how to verify it's warm
|
||||
|
||||
## Error-Fix Loop SOP (Standard Operating Procedure)
|
||||
|
||||
```
|
||||
1. Ensure devenv shell is active (IHP_LIB must be set)
|
||||
2. Run: scripts/compile-check --bg
|
||||
3. Monitor /tmp/ihub-compile-errors.txt
|
||||
4. Parse errors: group by module, order by Layer (1 → 4)
|
||||
5. Fix Layer 1 errors first (rare; usually type/import issues in Web/Types.hs)
|
||||
6. For each failing module in Layer 2–3:
|
||||
a. Read current module state
|
||||
b. Apply targeted fix
|
||||
c. Wait for ghcid "Reloading..." + result
|
||||
d. If still failing: re-read error, apply next fix
|
||||
e. If 3 attempts fail: note module name, move on
|
||||
7. After Layer 3 clean: fix Layer 4 (FrontController/Routes)
|
||||
8. "All good (N modules)" in log = build clean
|
||||
9. Commit fixes, update WP-0014/A1 status
|
||||
```
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- `scripts/compile-check` script exists and runnable inside devenv shell
|
||||
- `ghcid` produces output to `/tmp/ihub-compile-errors.txt` successfully
|
||||
- GHC object cache location identified and documented
|
||||
- ralph-workplan loop configuration in place
|
||||
- Build reaches "All good" state without user intervention beyond starting the loop
|
||||
Reference in New Issue
Block a user