generated from coulomb/repo-seed
fix(WP-0014/A2): close remaining pure-param and structural compilation errors
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>
This commit is contained in:
@@ -10,6 +10,7 @@ import Data.Aeson (object, (.=), encode, decode, Value, FromJSON(..), (.:), (.:?
|
||||
import qualified Data.Aeson as A
|
||||
import qualified Data.Aeson.KeyMap as KM
|
||||
import qualified Data.Aeson.Key as AK
|
||||
import qualified Data.Vector as V
|
||||
import qualified Data.ByteString.Lazy as LBS
|
||||
import System.Process (readProcessWithExitCode)
|
||||
import System.Exit (ExitCode(..))
|
||||
@@ -171,7 +172,7 @@ callBridgeBatch reqs = do
|
||||
let outBytes = LBS.fromStrict (cs stdout)
|
||||
case A.decode @A.Value outBytes of
|
||||
Just (A.Object o) | Just (A.Array arr) <- KM.lookup (AK.fromString "results") o ->
|
||||
pure $ map parseResult (toList arr)
|
||||
pure $ map parseResult (V.toList arr)
|
||||
_ ->
|
||||
pure $ replicate (length reqs) (Left (BridgeError "Unparseable batch output" "ParseError"))
|
||||
where
|
||||
@@ -217,5 +218,5 @@ checkGovernancePolicy hubId agentId artifactType = do
|
||||
-- | Extract Text values from a JSONB array.
|
||||
jsonArrayTexts :: Value -> [Text]
|
||||
jsonArrayTexts (A.Array vs) =
|
||||
[ t | A.String t <- toList vs ]
|
||||
[ t | A.String t <- V.toList vs ]
|
||||
jsonArrayTexts _ = []
|
||||
|
||||
@@ -21,11 +21,10 @@ checkRateLimitAndLog ::
|
||||
, ?request :: Request
|
||||
) =>
|
||||
ApiConsumer ->
|
||||
Text -> -- endpoint path
|
||||
Text -> -- HTTP method
|
||||
Int -> -- response status code (0 if not yet known; log after)
|
||||
Text -> -- endpoint path
|
||||
IO ()
|
||||
checkRateLimitAndLog consumer endpoint method _statusCode = do
|
||||
checkRateLimitAndLog consumer endpoint method = do
|
||||
-- Check rate limit: requests in last 60 seconds
|
||||
rows1 <- sqlQuery
|
||||
"SELECT COUNT(*) FROM api_request_log \
|
||||
|
||||
@@ -90,15 +90,15 @@ detectBottlenecks hubId hubWidgets candidates requirements decisions deployments
|
||||
|> set #hubId hubId
|
||||
|> set #stage stage
|
||||
|> set #subjectType subjType
|
||||
|> set #subjectId (coerce subjId)
|
||||
|> set #subjectId subjId
|
||||
|> set #stalledSince stalledSince
|
||||
|> set #severity severity
|
||||
|> createRecord
|
||||
|
||||
r1 <- mapM (\(c, t) -> mkBottleneck "candidate" "RequirementCandidate" c.id t candidateThreshold) staleCandidates
|
||||
r2 <- mapM (\(r, t) -> mkBottleneck "requirement" "Requirement" r.id t requirementThreshold) stalRequirements
|
||||
r3 <- mapM (\(d, t) -> mkBottleneck "decision" "DecisionRecord" d.id t decisionThreshold) staleDecisions
|
||||
r4 <- mapM (\(d, t) -> mkBottleneck "observation" "DeploymentRecord" d.id t observationThreshold) staleDeployments
|
||||
r1 <- mapM (\(c, t) -> mkBottleneck "candidate" "RequirementCandidate" (coerce c.id :: UUID) t candidateThreshold) staleCandidates
|
||||
r2 <- mapM (\(r, t) -> mkBottleneck "requirement" "Requirement" (coerce r.id :: UUID) t requirementThreshold) stalRequirements
|
||||
r3 <- mapM (\(d, t) -> mkBottleneck "decision" "DecisionRecord" (coerce d.id :: UUID) t decisionThreshold) staleDecisions
|
||||
r4 <- mapM (\(d, t) -> mkBottleneck "observation" "DeploymentRecord" (coerce d.id :: UUID) t observationThreshold) staleDeployments
|
||||
|
||||
pure (r1 <> r2 <> r3 <> r4)
|
||||
|
||||
|
||||
@@ -69,14 +69,16 @@ detectPropagations hubs annotations widgets frictionScores = do
|
||||
guard (not (any (\p -> p.patternType == "widget_type_friction" && p.summary == summary) existing))
|
||||
pure (srcHub, hubsWithHighFriction, "widget_type_friction", summary)
|
||||
|
||||
let allPatterns = clusterPropagations <> frictionPropagations
|
||||
let allPatterns :: [(Id' "hubs", [Id' "hubs"], Text, Text)]
|
||||
allPatterns = clusterPropagations <> frictionPropagations
|
||||
|
||||
mapM (\(srcHubId, affectedHubIds, ptype, summary) ->
|
||||
newRecord @CrossHubPropagation
|
||||
|> set #patternType ptype
|
||||
|> set #sourceHubId (Just srcHubId)
|
||||
|> set #affectedHubIds (toJSON (map show affectedHubIds))
|
||||
|> set #summary summary
|
||||
|> set #status "open"
|
||||
|> createRecord
|
||||
) allPatterns
|
||||
let insertPropagation (rawSrcId, affectedHubIds, ptype, summary) = do
|
||||
let srcId = rawSrcId :: Id' "hubs"
|
||||
newRecord @CrossHubPropagation
|
||||
|> set #patternType ptype
|
||||
|> set #sourceHubId (Just srcId)
|
||||
|> set #affectedHubIds (toJSON (map show affectedHubIds))
|
||||
|> set #summary summary
|
||||
|> set #status "open"
|
||||
|> createRecord
|
||||
mapM insertPropagation allPatterns
|
||||
|
||||
@@ -9,7 +9,8 @@ import Web.Routes ()
|
||||
import Database.PostgreSQL.Simple (Only(..))
|
||||
import Data.Time.Clock (addUTCTime, getCurrentTime)
|
||||
import qualified Data.Aeson as A
|
||||
import qualified Data.HashMap.Strict as H
|
||||
import qualified Data.Aeson.KeyMap as KM
|
||||
import qualified Data.Aeson.Key as AK
|
||||
|
||||
-- | Friction score formula (documented):
|
||||
--
|
||||
@@ -85,9 +86,9 @@ applyAdaptiveWeights hubId annCount errCount isRegressed staleCount = do
|
||||
mConfig <- query @AdaptiveThresholdConfig
|
||||
|> filterWhere (#hubId, hubId)
|
||||
|> fetchOneOrNothing
|
||||
let overrides = maybe mempty (.weightOverrides) mConfig
|
||||
let overrides = maybe (A.object []) (.weightOverrides) mConfig
|
||||
w k def = case overrides of
|
||||
A.Object o -> case H.lookup k o of
|
||||
A.Object o -> case KM.lookup (AK.fromText k) o of
|
||||
Just (A.Number n) -> round (n * fromIntegral def) :: Int
|
||||
_ -> def
|
||||
_ -> def
|
||||
|
||||
Reference in New Issue
Block a user