package requisite
Install
dune-project
Dependency
Authors
Maintainers
Sources
md5=5815b60dff170b0b553624c101d050e0
sha512=d787eed5aba9f090a6bd175f9c45d3e9f756d2339fce19c350050038cd7e25a8cb55ded9793d74c72dbb40a4431a1eeed5aeff020fb0a661ce2704bc7383cff4
doc/README.html
requisite
requisite puts a few data-handling requirements in OCaml types:
Trustseparates input from values that passed an application policy.Confidencevalidates probabilities, selects an action tier, and issues an abstractcertaintoken at the highest tier.Freshchecks a per-value TTL against a monotonic clock.
The library is small by design. It depends only on mtime for portable monotonic time.
Install
opam install requisiteThe package requires OCaml 4.14 or later.
Code that names Mtime.t or Mtime.span should declare mtime directly:
(libraries requisite mtime)requisite depends on mtime.clock internally, but Dune projects should not rely on transitive libraries for names used in their own source.
Trust transitions
open Requisite
let load_customer (id : (int, Trust.trusted) Trust.t) =
database_lookup (Trust.trusted_value id)
let raw = Trust.from_input request_body
let id =
Trust.try_sanitize raw (fun text ->
match int_of_string_opt (String.trim text) with
| Some id -> Ok id
| None -> Error `Bad_customer_id)Trust.t and its state markers are abstract. A trusted sink states its requirement in its argument type. sanitize and try_sanitize are the safe promotion paths; widen lowers a trusted value when an API asks for untrusted input.
The policy function defines “trusted” for the destination. Requisite records that the function succeeded, not that its policy was sufficient.
Confidence gates
let act (_ : Confidence.certain) decision =
commit decision
match Confidence.create ~probability:0.98 predicted_decision with
| Error invalid -> report_bad_score invalid.Confidence.value
| Ok scored ->
match Confidence.gate scored with
| Confidence.High_confidence (proof, decision) -> act proof decision
| Confidence.Likely decision -> queue_review decision
| Confidence.Unsure decision -> record decisionProbabilities must be finite and lie in [0, 1]. The default likely and certain boundaries are 0.60 and 0.95. Custom thresholds may raise the certain boundary, but cannot lower it:
let thresholds =
Confidence.Thresholds.create ~likely:0.75 ~certain:0.99The certain constructor is hidden. The token proves that some qualifying gate issued it; it is not tied to the score or payload that produced it. Ordinary OCaml code may store it, reuse it, or construct a new High_confidence value that pairs it with another payload. Keep the gate and authorized action close when that distinction matters.
Freshness
let ttl = Mtime.Span.( * ) 30 Mtime.Span.s
let quote = Fresh.fetch ~ttl price
match Fresh.read_with_stale quote with
| Ok price -> charge price
| Error expired ->
audit_expired_quote expired.Fresh.value;
Format.eprintf "%a@." Fresh.pp_stale expired.Fresh.staleFresh stores a monotonic timestamp for each value. read returns stale timing metadata; read_with_stale also returns the payload for an explicit recovery path. remaining saturates at zero. fetched_at accepts an existing Mtime.t and rejects timestamps ahead of the current clock.
A freshness result describes the instant of the check. OCaml does not make the returned payload expire later, so this is not a lease.
Mtime 2.x counts system suspend on Linux and supported modern macOS. Older macOS releases and other clock backends may differ; applications that require suspend to expire TTLs should verify their deployment platform.
Fresh wrappers are immutable and can be shared between threads or domains. Concurrent checks do not mutate the wrapper. This does not make a mutable payload safe for concurrent access.
Why there is no Live
The Rust library uses a higher-ranked lifetime to keep Live<'id, _> inside a closure. Standard OCaml has no equivalent lifetime or locality constraint for heap values. A rank-2 phantom brand blocks a direct return, but a caller can package the branded value in an existential GADT and use a polymorphic accessor after the callback. A generative first-class module has the same escape.
This port therefore omits Live rather than presenting that pattern as a compile-time scope guarantee. A revocable runtime handle is possible, but it is a different contract.
Enforcement boundaries
The abstractions hold for safe code using the public interfaces. Obj.magic, unsafe unmarshalling, or deliberately discarding wrappers can bypass them. Freshness and confidence thresholds are runtime checks. Trust policies remain application responsibilities.
Examples and development
dune exec examples/trust_flow.exe
dune exec examples/confidence_gate.exe
dune exec examples/fresh_cache.exe
dune fmt
dune build @all
dune runtest
dune build @doc
dune build --profile=ci @all @runtest @doc @installRuntime tests cover validation and boundary behavior. Compile-negative tests typecheck small programs against the public Trust and Confidence interfaces and require the compiler to reject attempts to forge or skip state transitions. Each case asserts diagnostic patterns so an unrelated typo cannot count as success. These tests use POSIX sh and are skipped on Windows; the portable runtime suite still runs there.
See CONTRIBUTING.md for the layout and release checks, and CHANGES.md for notable changes.
License
Licensed under either Apache-2.0 or MIT, at your option.