The inter-hub-lib postUnpack that expanded `import Generated.Types` to
119 individual imports was incorrect: it deleted `module Generated.Types`
from Prelude export lists without replacing it, so consumers of the
Prelude lost all entity types (Build 32: GHC-76037 not-in-scope errors).
Fix: keep Generated.Types as a real module in inter-hub-models (remove the
empty stub). With the ActualTypes.hi fix already in place (explicit T(..)
exports), the cascade is shallow: each entity .hi is compact, so
Generated.Types.hi stays well under GHC's 274 MB limit. This makes
`import Generated.Types` work normally throughout inter-hub-lib without
any source patching.
The entire inter-hub-lib overrideAttrs block is removed; the
inter-hub-models overlay now only rewrites ActualTypes.hs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: libHSghc-9.10.3-5702.a (287,768,576 bytes) has its last AR
entry (Expr.o) claiming 517,544 bytes but only 82,258 bytes remain —
the archive is truncated. GHC's internal readAr (Data.Binary.Get) panics
at position 287,686,318 when it tries to read the full claimed size.
The truncated .a is read lazily: IHP's TH splices queue a dependency on
the ghc package, which flushes to readAr after all 477 modules compile.
This explains the invariant crash at [477 of 477] WidgetVersionInclude.
ghc-iserv-dyn is not exposed in ghc-with-packages/bin/ (why
-fexternal-interpreter alone silently fell back to the internal linker).
Use -pgmi with the absolute path in the unwrapped GHC store to force
iserv-dyn, which uses dlopen on libHSghc.so (intact, 110 MB) instead
of readAr on the truncated .a. No crash.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
-fexternal-interpreter had no effect: crash invariant at 287,686,318.
System ar reads libHSghc-9.10.3-5702.a (287,768,576 bytes) fine, but GHC's
internal readAr fails on the last entry — a bug in GHC's AR parser when
reading content near end-of-file. The call site is mergeObjectFiles during
.so creation, not TH evaluation.
--disable-shared skips the shared library build for inter-hub-models,
preventing GHC from ever calling readAr on libHSghc.a.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GHC crashes at byte 287,686,318 reading libHSghc-9.10.3.a (~274 MB) via
its internal static linker during TH evaluation of WidgetVersionInclude.
-fexternal-interpreter delegates TH to a separate iserv process using the
dynamic linker, bypassing readAr and the 274 MB archive entirely.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
With -j8, GHC generates code for 8 modules in parallel. A parallel merging
step might read combined objects via Data.Binary.Get hitting 287 MB. Forcing
-j1 serializes codegen to test if parallel merging is the crash cause.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DynamicToo state: DT_Dyn appears right before the crash. Force separate
static and dynamic GHC compilation passes to change the code path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Crash invariantly at position 287,686,318 bytes happens after all 477 modules
compile. Hypothesis: split-sections expands ELF section count, triggering
GHC's internal ELF merger/linker to fail when reading the combined object.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>
IHP entity pattern: data Foo' params = Foo {...} (primed type, unprimed ctor)
type Foo = Foo' arg1 arg2 (concrete alias, kind *)
Include type instances use [Foo] — needs the concrete type alias (kind *),
not the primed data type. Previous awk only matched data/newtype, missing
the type alias. Add /^type [A-Z]/ match (no (..) suffix — type aliases are
not ADTs). type instance lines start with lowercase 'i' and don't match.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous attempt (stubs + direct imports) broke qualified constructor
references like Generated.ActualTypes.WidgetVersion in Include files —
removing the hub from scope invalidated all qualified names through it.
New approach: rewrite Generated.ActualTypes.hs in postUnpack to replace
the `module M` export list with explicit T(..) re-exports. Explicit
re-exports store only name references in the .hi file (compact), while
`module M` embeds the full sub-interface (~287 MB for 61 modules). Hub
stays functional — consumers still qualify via Generated.ActualTypes.
Also deduplicate with sort -u in case PrimaryKeys and entity files both
declare the same ID type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated.ActualTypes uses `module M` re-export syntax for 61 sub-modules;
GHC 9.10.3 embeds all 61 full sub-interfaces into ActualTypes.hi (~287 MB),
hitting the binary-deserialization limit at position 287686318.
Revert Cabal sub-library split (did not help — models-inner also crashed
with only 61 modules at the same invariant position). Apply the same fix
already working for Generated.Types in inter-hub-lib:
- inter-hub-models postUnpack: stub Generated.ActualTypes.hs + Generated.Types.hs
to empty modules; patch every importer with direct sub-module imports (reads
original ActualTypes.hs before stubbing to build the replacement import list)
- inter-hub-lib postUnpack: same for both hubs (each package has its own
sourceRoot with originals intact)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
cabal-version: 2.2 does not support the pkg:sublibrary reference
syntax. Bump to 3.0 which explicitly supports it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
GHC 9.10.3 crashes with Data.Binary.Get.runGet at position 287686318
invariantly when compiling all 476 inter-hub-models modules in a single
--make invocation. Split into two library components to force two
separate GHC compilations:
models-inner (~63 modules): Generated.ActualTypes.* + Generated.Enums
Pure type definitions; zero inter-hub-models dependencies.
main library (~413 modules): entity ops + Include instances
Depends on models-inner.
Longer-term this is the right architecture: explicit boundaries reduce
build cost, isolate changes, and make diagnostics cheaper.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated.ActualTypes uses "module M" for 61 sub-modules, causing GHC
to embed each sub-interface verbatim into ActualTypes.hi. That file hits
the GHC 9.10.3 Data.Binary.Get 274 MB limit (position 287686318) when
WidgetVersionInclude reads it during inter-hub-models compilation.
Removing the explicit (module M, ...) export list keeps the same
re-export semantics (no explicit list = export all imports) but forces
GHC to store compact name-reference entries instead of embedded copies.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Nix ''...'' strings interpolate \${...} — use ''$ to produce a literal
dollar sign so bash sees TypesPart\${_k}.hs not Nix interpolation.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2-way split (60 entities per part) still crashes: TypesPart1.hi itself
reaches 287 MB due to mandatory type-class instance data per IHP entity.
4-way split (~30 entities each, ~150 MB .hi) stays safely under the limit.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Previous attempt failed: inter-hub-models is not a named attribute in
haskellPackages (IHP creates it via callCabal2nix locally), so the
hasAttr guard bailed silently.
New approach: override callCabal2nix itself. When called with
name == "inter-hub-models", inject a postUnpack phase that copies
TypesPart1/TypesPart2 into the build sandbox and replaces Types.hs
with the thin wrapper. Applied to both haskellPackages and
haskell.packages.ghc910 to cover whichever set IHP uses.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generated.Types imports 119 modules, pushing the combined .hi read past
a ~287 MB binary-deserialization limit in GHC 9.10.3. Fix by adding a
nixpkgs overlay that patches the inter-hub-models derivation: replaces
Generated/Types.hs with a thin TypesPart1/TypesPart2 re-export wrapper
after build-generated-code runs, and adds the two split modules to the
cabal exposed-modules list.
Also fix the production binary name from /bin/App to /bin/RunProdServer
in deployment.yaml and RUNBOOK.md (the IHP NixSupport build produces
RunProdServer, not App). Switch packages.docker to IHP's built-in
unoptimized-docker-image which already uses the correct binary path.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IHP cabal executable is named 'App' (not 'inter-hub'), matching the
executable declaration in App.cabal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
packages.docker using dockerTools.buildLayeredImage wraps the IHP
production binary with cacert for Anthropic API calls. Push target:
92.205.130.254:32166/coulomb/inter-hub:TAG via skopeo.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Convert all remaining `<- paramOrNothing / param / paramOrDefault /
currentUserOrNothing` monadic binds to `let` — these functions are pure
(ImplicitParams-based) in IHP v1.5, so `<-` is a type error in an IO
do-block.
Controllers fixed:
AgentDelegations, AiGovernancePolicies, Annotations, ApiConsumers,
CollectiveProposals, DecisionRecords, DeploymentRecords,
HubCapabilityManifests, HubRoutingRules, InstitutionalKnowledge,
OutcomeCorrelations, RequirementCandidates, TypeRegistries,
WebhookSubscriptions, Widgets,
Api/V2/{Annotations,InteractionEvents,Token}
WebhookSubscriptions: remove orphaned `Right () ->` case arm that was
left inside a bare `unless` block (structural parse error).
Also carries forward all in-progress fixes from the working tree:
helpers (AgentBridge, ApiRateLimit, BottleneckDetector,
CrossHubPropagation, FrictionScore),
views (CanSelect instances, HSX lambda extraction, formFor wrappers),
env/build (envrc GHCi perms, flake.nix Tailwind + GHC resource limits,
static/app.css additional Tailwind output).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds bounded AI support to the IHF governance loop. All AI outputs are
attributed (model_ref), reviewable (AgentReviewRecord), and reversible.
No autonomous decisions; no silent requirement promotion.
- T01: Schema — agent_proposals, agent_review_records,
confidence_annotations (migration 1743379200)
- T02: AgentProposalsController (index/show/accept/reject, idempotent
review guard), global nav "Agent" link
- T03: SummarizeClusterAction — Claude API cluster summary on widget show
- T04: DraftRequirementAction — AI requirement draft; acceptance creates
RequirementCandidate (human-gated)
- T05: DetectDuplicatesAction — duplicate_flag proposal on candidate show
- T06: DetectPolicySensitivityAction — policy_flag with
ConfidenceAnnotations per concern scope
- T07: ProposeImplementationAction — impl_proposal from decision show
- T08: AgentAuditDashboardAction — autoRefresh; KPI row, unreviewed queue,
recent proposals, attribution log matrix
- T09: integration tests, SCOPE.md updated, phase5-summary.md, flake.nix
adds http-conduit/aeson/string-conversions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>