| Safe Haskell | None |
|---|---|
| Language | GHC2021 |
Ecluse.Core.Package.Admission
Description
The single public-version admission gate, shared by the serve path and the mirror worker.
Admitting a public version to a concrete artifact request is a three-step decision:
the rules engine decides the version (evalRules), the
requested filename selects the artifact (artifactFor), and the
integrity-floor admission policy decides whether that artifact's digests are
strong enough to gate (classifyArtifacts). Both
consumers of that decision -- the serve pipeline's public tarball gate and the
mirror worker's ingest-time re-evaluation -- call the one admitArtifact here, so
the two contexts cannot drift: a version the worker would freeze into the
rule-exempt mirror is exactly a version the serve gate would admit, and a
tightened policy (a new deny rule, a raised floor, a withdrawn file) refuses it in
both places for the same reason. Each context projects the shared
ArtifactAdmission onto its own surface (an HTTP status, a queue ack/redeliver),
and those projections are total, so a new admission outcome cannot be silently
ignored by either.
Synopsis
- data ArtifactAdmission
- admitArtifact :: EvalContext -> [PreparedRule] -> MinIntegrity -> Text -> PackageDetails -> IO ArtifactAdmission
- artifactFor :: Text -> PackageDetails -> Maybe Artifact
Documentation
data ArtifactAdmission Source #
The admission verdict for one requested artifact of one public version -- the shared vocabulary both the serve gate and the worker's ingest re-evaluation project onto their own surfaces.
The constructors separate the deliberate refusals (a rule denial, an
integrity-policy refusal, an absent file) from the inability to decide
(AdmissionUndecidable), because the two consumers act on that split differently:
serve renders a denial 403 and an inability 503/500, the worker retires a
denied job (ack, never publish) and leaves an undecidable one to redeliver.
Constructors
| AdmissionAdmit Artifact (NonEmpty Hash) | The rules admitted the version, the requested filename selected an artifact, and its digests clear the integrity floor: serve it / mirror it. Carries the artifact and its integrity digests exactly as the floor checked them, non-empty as a fact of admission, so both consumers act on this one floor-checked set (the serve pipeline captures it on the mirror job it enqueues; the worker's tamper gate verifies the fetched bytes against it) rather than each re-deriving and re-guarding it from the artifact. |
| AdmissionDenied Decision | A rule (or deny-by-default) blocked the version. Carries the |
| AdmissionUndecidable Decision | The version could not be decided (a fail-closed rule whose evaluation was
unavailable). Carries the |
| AdmissionFileAbsent | The rules admitted the version but no artifact carries the requested filename: a forwarded miss on the serve path, a withdrawn-file drop at the worker -- never a fabricated location. |
| AdmissionIntegrityMissing | The selected artifact carries no integrity digest of any kind, so its
bytes cannot be tied to a tamper-evident fingerprint. Refused by the
admission policy (deny-by-default), distinct from |
| AdmissionBelowFloor | The selected artifact carries digests, but none meets the configured public-integrity floor (e.g. a legacy SHA-1 shasum only, under the SHA-256 floor). Refused by the admission policy. |
Instances
| Show ArtifactAdmission Source # | |
Defined in Ecluse.Core.Package.Admission Methods showsPrec :: Int -> ArtifactAdmission -> ShowS # show :: ArtifactAdmission -> String # showList :: [ArtifactAdmission] -> ShowS # | |
Arguments
| :: EvalContext | |
| -> [PreparedRule] | |
| -> MinIntegrity | |
| -> Text | The requested artifact filename (the client's, or the mirror job's). |
| -> PackageDetails | |
| -> IO ArtifactAdmission |
Decide one requested artifact of one public version under current policy: the rules first (the engine's first decisive verdict), then artifact selection by the requested filename, then the integrity-floor admission policy over the selected artifact.
The rules run first so an artifact-level refusal never masks a version-level denial, and no integrity classification is paid for a version a rule already denies. The floor is applied to the selected artifact only (the one whose bytes would be served or mirrored), exactly as the serve path has always gated it.
This is the one admission decision for both contexts. The serve pipeline calls it on a public tarball request; the mirror worker calls it at ingest with the same prepared rules, the same clock, the same configured floor, and the job's own filename -- so the enqueue → process window can only ever narrow what is mirrored (policy tightened, file withdrawn), never admit past the serve gate.
artifactFor :: Text -> PackageDetails -> Maybe Artifact Source #
Select the artifact a request's filename names from a version's distribution
files. npm has exactly one artifact per version, so the match is the single file; a
many-per-version ecosystem (PyPI) would select the wheel/sdist whose filename the
client requested. Nothing when no artifact carries the requested filename -- a
forwarded miss, never a fabricated location.