fix: resolve all GHC 9.10.3 / IHP 1.5 compile errors (all 616 modules load)
Some checks failed
Test / test (push) Has been cancelled

Fix 13 modules that blocked compilation on Alpine:

- FrontController: remove annotationLauncherScript helper (IHP Html is a
  constrained type synonym); add (?context, ?request) constraint to
  defaultLayout matching what setLayout expects
- HubCapabilityManifests: switch JSONB fill to paramList+toJSON; fix dynamic
  SQL Text→Query via fromString/cs; void sqlExec; add Control.Monad.void
- Hubs: replace raw Array sqlQuery with filterWhereIn query builder;
  fix isInList validators
- DecisionRecords: remove unregistered DistilDecisionAction; fix hub
  resolution chain via candidateId→sourceWidgetId; BridgeResponse(..)
- RequirementCandidates: BridgeResponse(..); remove @Widget type apps from
  fetchOneOrNothing; void ConfidenceAnnotation createRecord
- AdaptiveThresholds: fix sqlQuery tuple param (Only hubId)
- AgentDelegations, AgentRegistrations, Widgets: BridgeResponse(..)
- Annotations, DeploymentRecords, GovernanceTemplates: minor type fixes
- DecisionRecords/Edit view: extract formAction before HSX block

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 10:46:50 +02:00
parent 209c77dd31
commit 2106000cc7
13 changed files with 71 additions and 130 deletions

View File

@@ -8,9 +8,8 @@ import Web.View.DecisionRecords.Edit
import Generated.Types
import IHP.Prelude
import IHP.ControllerPrelude
import Application.Helper.AgentBridge (callAgent, checkGovernancePolicy, bridgeErrorMessage, BridgeResponse)
import Application.Helper.AgentBridge (callAgent, checkGovernancePolicy, bridgeErrorMessage, BridgeResponse(..))
import Application.Helper.ModelRouter (resolveAgent)
import Data.List (intercalate)
import IHP.ModelSupport (sqlQuery)
import qualified Data.Aeson as A
import Data.Coerce (coerce)
@@ -95,7 +94,7 @@ instance Controller DecisionRecordsController where
|> set #decidedBy (fmap coerce decidedBy)
|> validateField #title nonEmpty
|> validateField #rationale nonEmpty
|> validateField #outcome (`elem` validOutcomes)
|> validateField #outcome (isInList validOutcomes)
|> ifValid \case
Left record -> render NewView { record, requirements, candidates, users }
Right record -> do
@@ -188,10 +187,14 @@ instance Controller DecisionRecordsController where
mRequirement <- case record.requirementId of
Nothing -> pure Nothing
Just rid -> fetchOneOrNothing rid
-- Resolve hub from the source widget via requirement candidate
mHubId <- case mRequirement >>= (.sourceWidgetId) of
-- Resolve hub via the decision's linked candidate → source widget
mHubId <- case record.candidateId of
Nothing -> pure Nothing
Just wid -> fmap (.hubId) <$> fetchOneOrNothing @Widget wid
Just cid -> do
mCand <- fetchOneOrNothing cid
case mCand of
Nothing -> pure Nothing
Just cand -> fmap (.hubId) <$> fetchOneOrNothing cand.sourceWidgetId
let implLines = map (\r -> r.system <> ": " <> r.workItemRef) implRefs
reqDesc = maybe "" (.description) mRequirement
userMsg = "Decision: " <> record.title
@@ -243,59 +246,3 @@ instance Controller DecisionRecordsController where
setSuccessMessage "Implementation proposal created"
redirectTo ShowDecisionRecordAction { decisionRecordId }
-- T05 / Phase 12: Distil decision into institutional knowledge entry
action DistilDecisionAction { decisionRecordId } = do
record <- fetch decisionRecordId
outcomes <- sqlQuery
"SELECT os.signal_type, os.value FROM outcome_signals os \
\ JOIN deployment_records dep ON dep.id = os.deployment_id \
\ WHERE dep.decision_id = ?"
[decisionRecordId]
:: IO [(Text, Maybe Double)]
let signalText = intercalate ", " $
map (\(st, mv) -> st <> maybe "" (\v -> "=" <> show v) mv) outcomes
prompt = "Distil this decision into a 2-3 sentence institutional knowledge entry. "
<> "Include the outcome data.\n\nDecision: " <> record.title
<> "\nRationale: " <> record.rationale
<> "\nOutcome: " <> record.outcome
<> "\nSignals: " <> signalText
-- Resolve hub from requirement chain
mHubId <- case record.requirementId of
Nothing -> pure Nothing
Just rid -> do
mReq <- fetchOneOrNothing rid
pure $ case mReq >>= (.sourceWidgetId) of
Nothing -> Nothing
Just _ -> Nothing -- hub resolution via widget lookup below
mHubIdResolved <- case record.requirementId of
Nothing -> pure Nothing
Just rid -> do
mReq <- fetchOneOrNothing rid
case mReq >>= (.sourceWidgetId) of
Nothing -> pure Nothing
Just wid -> fmap (.hubId) <$> fetchOneOrNothing @Widget wid
case mHubIdResolved of
Nothing -> do
setErrorMessage "Cannot resolve hub — ensure decision has a linked requirement with a source widget"
redirectTo ShowDecisionRecordAction { decisionRecordId }
Just hubId -> do
mAgent <- resolveAgent hubId "synthesis"
case mAgent of
Nothing -> do
setErrorMessage "No routing policy for 'synthesis' task type"
redirectTo ShowDecisionRecordAction { decisionRecordId }
Just agent -> do
result <- liftIO $ callAgent agent prompt
case result of
Left err -> do
setErrorMessage ("Distillation failed: " <> bridgeErrorMessage err)
redirectTo ShowDecisionRecordAction { decisionRecordId }
Right resp -> do
newRecord @InstitutionalKnowledgeEntry
|> set #hubId hubId
|> set #decisionRecordId (Just decisionRecordId)
|> set #summary resp.content
|> set #tags (A.toJSON ["decision" :: Text])
|> createRecord
setSuccessMessage "Knowledge entry created"
redirectTo ShowDecisionRecordAction { decisionRecordId }