ecluse:ecluse-core
Safe HaskellNone
LanguageGHC2021

Ecluse.Core.Server.Pipeline.Internal

Description

Internal guts of the serve pipeline (Ecluse.Core.Server.Pipeline), exposed for tests without widening that module's two-handler public API -- the .Internal convention, as Ecluse.Core.Credential.Refresh.Internal uses. Importing it opts out of the public module's stability promise.

It holds the operator-facing warning helpers for two bad-upstream conditions the response-bound guards leave silent -- an upstream whose body does not decode into a usable packument (logDecodeFailure), and one whose packument self-reports a name for a different package (logNameMismatch) -- each surfaced at a WarningS through the ambient katip context before the contribution degrades. The conditions themselves are classified on the serve path as a typed MetadataError; this module only renders their warning lines. Alongside them sit the pure integrity-floor admission and the metric-label projections the serve path records.

Synopsis

Documentation

logDecodeFailure :: KatipContext m => PackageName -> m () Source #

Log a parse failure at WarningS -- the one bad-upstream condition the response-bound guards leave silent: the upstream answered, but its body did not decode into the typed view and raw document the serve path needs. Same fail-closed degrade and the same module/package payload convention as the breach log in Ecluse.Core.Server.Pipeline, so an operator sees an undecodable upstream distinctly rather than as silence. Emitted through the ambient katip context (the request's, so the line carries its trace-correlation dd).

logNameMismatch :: KatipContext m => PackageName -> Text -> Text -> m () Source #

Log an upstream name mismatch at WarningS before the contribution degrades: the origin answered, but its packument self-reported a name for a different package than the one requested, so it is dropped as untrusted for this request. The structured payload carries both names and the origin (its base URL) -- the high-cardinality identifiers that belong on the log line -- so an operator can tell a misconfigured or hostile upstream from an ordinary outage. Same fail-closed degrade and payload convention as logDecodeFailure.

Integrity-floor admission (pure)

admitByIntegrity :: IntegrityFloor floor => floor -> ServeDecision -> ServeDecision -> PackageInfo -> (PackageInfo, [ServeDecision]) Source #

Apply an integrity-floor admission policy to a PackageInfo, keeping only the versions whose strongest digest meets the floor and projecting the rest to refusals. A version whose digests are all weaker than the floor (or absent) cannot be tied to a floor-strength tamper-evident fingerprint, so it is dropped from the served listing rather than served a client could never safely verify. Used by both gates: the public gate (gatePublic) with the hard-floored MinIntegrity, and the trusted gate (admitTrusted) with the loosenable MinTrustedIntegrity. Returns the admissible PackageInfo (with dist-tags pruned to the kept keys, exactly as restrictToSurvivors prunes for the rules; each kept version carries its own publish time, so restricting the versions carries the times with it) and the refusals for the dropped versions: BelowIntegrityFloor for a too-weak digest, MissingIntegrity for none at all, each feeding the no-survivors status.

Metric-label projections (pure)

packumentServeDecision :: [ServeDecision] -> Decision Source #

Classify a no-survivors packument outcome into the bounded ecluse.serve.decision value: a forbidden set is a denial, any other non-served status a transient unavailability. (A served set is recorded as an admit at the call site, not here.)

serveDecisionClass :: ServeDecision -> Decision Source #

Classify a single artifact-path serve decision into the bounded metric decision: a policy or integrity refusal is a denial, an upstream outage or invalid response an unavailability.

denialLabels :: RejectReason -> (Maybe Text, ReasonClass) Source #

Map a reject reason to the ecluse.rule.denials labels: the deciding rule (only a policy denial names one) and the bounded reason class.

evalTier :: [PreparedRule] -> Tier Source #

The rule-evaluation tier a duration is attributed to, from the mount's rule set: a mount with any resilient (effectful) rule is attributed to the effectful tier; a purely-pure rule set reduces to the structural tier. The resilience policy a prepared rule carries -- not a separate list -- is what distinguishes an effectful rule now that the two tiers are one engine.

transienceCause :: Transience -> Cause Source #

Map an undecidable verdict's transience to the bounded ecluse.rule.effectful.failures cause: a retryable cause is a connection-class fault (the source was unreachable now), a permanent one the catch-all other.

Metric emits (off a serve outcome)

recordDenials :: MetricsPort -> [ServeDecision] -> IO () Source #

Record the ecluse.rule.denials counter for each rejected decision, labelled by the bounded reason class and -- for a policy denial -- the deciding rule name (denialLabels). An admit records nothing.

recordEffectfulFailures :: MetricsPort -> [Decision] -> IO () Source #

Count each effectful-rule failure among a packument's per-version decisions: an Undecidable is an effectful rule whose source could not be consulted, so it is the effectful-failure signal, classified to a bounded cause by its transience (transienceCause). A decided version (allowed or denied) is not a failure.