valis / Reference / API reference

Active modules - API reference

Exported surface for the active subsystem. Part of the API reference.

Package valis/src/active/acme-listeners

Conditions

challenge-certificate-error

Signalled when the installed tls-alpn-01 challenge certificate cannot be made into a certificate chain to present. It is a fault in what was installed, never a transport event, so the accept loop reports it as a server-side failure rather than as a connection that merely ended.

Functions

call-with-http01-responder

(call-with-http01-responder listener-capability host body-fn &key inherited-socket)

Stand up a transient http-01 responder, call BODY-FN with (SOLVER SOCKET) — a mercer :install/:remove solver plist and the live listening socket — and tear the responder down under unwind-protect on every exit path. The solver's :install registers a token's key-authorization; the responder serves it as plaintext at /.well-known/acme-challenge/<token>; :remove drops it.

The listening socket comes from one of two sources, and its provenance governs teardown:

  • INHERITED-SOCKET, when supplied, is an already-listening usocket socket derived from an inherited :80 descriptor fulcrum steers in. The responder drives accept on it WITHOUT its own bind-listen (LISTENER-CAPABILITY and HOST are unused on this path), and teardown does NOT close it — fulcrum owns the descriptor lifecycle and its listen backlog.
  • With no inherited socket, valis owns the bind through LISTENER-CAPABILITY (bound on HOST) and teardown closes the valis-bound socket.

call-with-tls-alpn01-responder

(call-with-tls-alpn01-responder listener-capability host body-fn)

Stand up a transient tls-alpn-01 responder on the valis-owned listener the LISTENER-CAPABILITY grants (bound on HOST), call BODY-FN with (SOLVER SOCKET) — a mercer :install/:remove solver plist and the live listening socket — and tear the responder down under unwind-protect on every exit path. :install registers the domain's synthetic challenge cert + ephemeral key; each accepted connection presents it over acme-tls/1; :remove drops it. The ephemeral key is mercer's throwaway challenge key, never a leaf key.

Macros

with-http01-responder

(with-http01-responder (solver socket listener-capability &key (host "0.0.0.0") inherited-socket) &body body)

Stand up a transient http-01 responder, bind SOLVER to the mercer :install/:remove solver plist and SOCKET to the live listening socket, evaluate BODY (the order), and retract the responder on every exit path (unwind-protect). Pass (list :http-01 SOLVER) to obtain-certificate.

With no INHERITED-SOCKET valis owns the bind through LISTENER-CAPABILITY (bound on HOST) and closes it on teardown. INHERITED-SOCKET, when supplied, is an already-listening socket derived from an inherited :80 descriptor fulcrum steers in: the responder serves over it without its own bind-listen and leaves it open on teardown (fulcrum owns the descriptor).

with-tls-alpn01-responder

(with-tls-alpn01-responder (solver socket listener-capability &key (host "0.0.0.0")) &body body)

Stand up a transient tls-alpn-01 responder over the granted LISTENER-CAPABILITY, bind SOLVER to the mercer :install/:remove solver plist and SOCKET to the live valis-owned listening socket, evaluate BODY (the order), and retract the responder on every exit path (unwind-protect). Pass (list :tls-alpn-01 SOLVER) to obtain-certificate.

Variables

+acme-challenge-path-prefix+

The RFC 8555 §8.3 http-01 request path prefix. The CA GETs this prefix followed by the challenge token; the responder answers with the token's key-authorization.

+acme-tls-alpn-protocol+

The RFC 8737 tls-alpn-01 ALPN protocol identifier the responder negotiates.

Package valis/src/active/acme-manager

Classes

acme-manager

The ACME manager's live handle: the alist of granted (designation . capability) it was handed at :start, and nothing else. Every seam it drives is looked up in this alist — the module holds no substrate global.

Conditions

certificate-without-identifiers

Signalled by a renewal driver when the held leaf claims no subjectAltName DNS entries. Ordering an empty identifier set would be a request for a certificate covering nothing, so the driver refuses instead of guessing a name.

missing-account-contact

Signalled by obtain-initial-certificate when the account-contact is NIL or empty, BEFORE any order is driven — the fail-closed refusal. The report names the missing contact by role only and never prints the contact value, so operator PII never reaches a log or a backtrace.

non-production-ca-refused

Signalled by a renewal driver before any identifier work and before any order, when the resident names a served public edge but the production opt-in is not set. It is the refusal that keeps a staging leaf from replacing a trusted one.

unsatisfiable-identifier

Signalled by select-challenge when NO available method can satisfy an identifier — the fail-closed refusal raised BEFORE any order is placed.

Generic functions

certificate-without-identifiers-domain

(certificate-without-identifiers-domain condition)

Undocumented: this exported symbol needs a docstring.

non-production-ca-refused-domain

(non-production-ca-refused-domain condition)

Undocumented: this exported symbol needs a docstring.

non-production-ca-refused-edge-domain

(non-production-ca-refused-edge-domain condition)

Undocumented: this exported symbol needs a docstring.

unsatisfiable-identifier-available

(unsatisfiable-identifier-available condition)

Undocumented: this exported symbol needs a docstring.

unsatisfiable-identifier-identifier

(unsatisfiable-identifier-identifier condition)

Undocumented: this exported symbol needs a docstring.

Functions

acme-manager-capabilities

(acme-manager-capabilities instance)

Undocumented: this exported symbol needs a docstring.

acme-manager-p

(acme-manager-p object)

Undocumented: this exported symbol needs a docstring.

attempt-renewal

(attempt-renewal cert-id renew-fn &key (now (get-universal-time)))

Run ONE renewal attempt for CERT-ID via RENEW-FN (the order thunk returning the next-renewal instant, and OPTIONALLY the freshly-issued material to hot-swap as a second value) and RETURN this task's own next-fire. On SUCCESS record a healthy outcome (consecutive-failures→0) FIRST, then best-effort hot-swap the live :443 cert in place when the renewal carried fresh material — the recorder runs before the swap, so a swap miss never demotes a genuinely successful renewal — and return the next ARI/heuristic fire. On FAILURE — never silently — write the durable renewal-health row (last-error, consecutive-failures++, next-retry), emit a log4cl ERROR carrying substrate facts only (the identifier and the error class, never key bytes or CA text as a format directive), and return an exponential-backoff next-fire so the scheduler reschedules. The task returning its own next-fire is what lets ARI and backoff both flow through the scheduler with no special-casing.

authoritative-for-identifier?

(authoritative-for-identifier? identifier authoritative-zones)

T when valis serves IDENTIFIER's zone — IDENTIFIER is at or under one of AUTHORITATIVE-ZONES (the canonical origins ndb holds). A leading wildcard label is ignored, since the wildcard and its apex share one zone.

call-with-dns01-published

(call-with-dns01-published zone-write-capability origin owner txt body-fn &key (await (lambda nil t)))

Publish the dns-01 challenge TXT member (OWNER, TYPE :txt, TTL, TXT) into the zone at ORIGIN through ZONE-WRITE-CAPABILITY, run BODY-FN, and RETRACT the member on EVERY exit path under the manager's OWN unwind-protect — so a forced error still leaves the zone byte-identical to its pre-publish state. AWAIT is polled after publish for self-NS visibility; if it reports the member missing (a full-zone re-import wiped it between publish and the CA poll, the single-writer boundary), the member is re-published once before BODY-FN runs. Returns BODY-FN's value.

compute-backoff

(compute-backoff failure-count now)

The exponential-backoff next-fire: NOW plus base·2FAILURE-COUNT, capped. A growing FAILURE-COUNT yields a growing delay.

custody-renewal-entries

(custody-renewal-entries &key store-path)

The certs held in the ACME custody store rooted at STORE-PATH, as the entry plists the renewal clock, the expiry belt and the STATUS line all read: :cert-id the domain, :certificate its held leaf chain PEM, :renew-fn its renewal driver. A NIL STORE-PATH takes mercer/boomer's own default store location.

The store is built the same way an initial order builds it, so the entries describe exactly the store the edge loads its certificate from.

This NEVER signals. It runs inside the module's :start thunk, where an escaping condition would take the boot down. But it does not fall back quietly either: a store that cannot be read emits an ERROR event naming the fault class before the empty list is returned, so an unreadable store is distinguishable at the log from a store that genuinely holds nothing. A quiet empty list here is how the renewal schedule stayed empty unnoticed.

Called on every health-loop iteration through the STATUS line, not only at boot, so it stays at one directory listing plus one file read per domain.

group-identifiers-by-topology

(group-identifiers-by-topology identifiers authoritative-zones available-methods)

Partition IDENTIFIERS by their selected challenge type into an alist (challenge-type . identifiers), so one order groups only identifiers that share a topology (mercer runs one challenge type per order). Fail-closed: an unsatisfiable identifier signals before any grouping is returned, so no order is ever attempted for it.

make-custody-renewal-driver

(make-custody-renewal-driver store domain)

Return the nullary thunk that renews DOMAIN's leaf inside STORE: the :renew-fn a custody entry carries to the scheduler, returning (values next-renewal-instant reload-plist) exactly as attempt-renewal expects.

The thunk re-orders the names the HELD certificate claims in its subjectAltName, never a name derived from the store's directory layout: a leaf covering both an apex and its wildcard must come back covering both, and a name guessed from the directory would silently narrow the certificate at its first renewal.

It obtains into the store it was HANDED, not into whatever store the edge configuration currently names. The two coincide on a deployed node and diverge under a scratch fixture, so enumerating one store while writing to another is a defect that would surface far from where it was introduced.

It refuses, before any identifier work and before any order, when this resident names a served public edge and the production opt-in is absent: boomer's store writes a renewed leaf over the same fullchain.pem the edge serves, so a renewal driven against a staging authority would replace a trusted production certificate with one no browser accepts. The refusal is loud by construction, since attempt-renewal records the durable failure row, emits an ERROR and backs off, so a misconfigured node is visible rather than quietly downgraded.

The reload plist asking for an in-process hot swap comes back ONLY for the one domain the edge is actually serving. The reloader ignores the domain it is handed and swaps the single credential the edge holds, so a plist for any other domain would put the wrong certificate on the live listener. The two names are compared normalized and case-insensitively because they arrive from different places: the served name is operator-supplied and only whitespace-trimmed, while the custody name comes from a directory listing. A raw EQUAL would miss on a trailing dot or a difference of case, and that miss withholds the plist for the served domain too, disabling the hot swap permanently and silently while renewals keep succeeding.

make-dns01-solver

(make-dns01-solver zone-write-capability authoritative-zones &key (await-fn (lambda (owner txt) (declare (ignore owner txt)) t)))

Build the mercer dns-01 challenge-solver plist (:publish/:retract) over ZONE-WRITE-CAPABILITY. mercer calls :publish with the full challenge name and the TXT value; the closure derives (origin owner) against AUTHORITATIVE-ZONES, publishes through the zone-write seam (carrying the live fence generation), and polls AWAIT-FN for self-NS visibility before returning so the CA sees the record. mercer wraps the matching :retract in its own order-loop unwind-protect.

normalize-ca-identifier

(normalize-ca-identifier identifier)

IDENTIFIER as the CA expects it: the DNS name with any trailing dot stripped. valis holds zone origins in canonical absolute (trailing-dot) form, but RFC 8555 order identifiers are relative dotless names — an ACME server (Pebble included) rejects an identifier that carries a trailing period. The dotless counterpart to %ensure-dot, to apply to every identifier threaded to an order so a zone origin never reaches the CA in absolute form.

obtain-initial-certificate

(obtain-initial-certificate identifiers &key account-contact profile store-path directory-url authoritative-zones await-fn)

Compose and DRIVE an INITIAL dns-01 order for IDENTIFIERS — the first-obtain call site the resident lacked (the manager could only reschedule renewals). Groups IDENTIFIERS by topology over valis's authoritative zones (dns-01 only, so a non-authoritative identifier is REFUSED fail-closed before any order), builds the zone-write and CA-transport capabilities under the manager's own designations, builds the dns-01 solver over the zone list with a bounded self-NS wire-visibility await, and drives the dns-01 group through first-obtain-driver.

ACCOUNT-CONTACT is mandatory and threaded to the order; a NIL or empty contact signals MISSING-ACCOUNT-CONTACT BEFORE the driver is called (mercer wraps the contact as "mailto:<contact>" unconditionally, so a NIL contact would register as "mailto:NIL" and be rejected). PROFILE defaults to ca-order-profile; see there for what an unset value actually sends. STORE-PATH defaults to resolve-edge-acme-store-path, so the issued cert lands in the SAME store load-edge-credential-cell reads at boot — a green order never boots :443 cert-gated-dark into a store it wrote elsewhere. DIRECTORY-URL is left to the config-gated default (staging unless the explicit production opt-in); the Pebble-only CA-TLS verification bypass is NEVER forwarded — the production path always verifies the CA's TLS certificate. Returns (values certificate-pem next-renewal-instant).

rederive-renewal-schedule

(rederive-renewal-schedule manager &key (now (get-universal-time)))

Re-derive the renewal schedule from mercer cert custody on boot: enumerate the certs in custody, compute each next-renewal, and post a renewal task at that instant. A next-fire in the past fires immediately (catch-up). Empty custody schedules nothing.

schedule-renewal

(schedule-renewal manager cert-id fire-at renew-fn)

Post CERT-ID's renewal task at FIRE-AT (absolute universal-time) on MANAGER's granted scheduler. A FIRE-AT in the past fires immediately (catch-up). A no-op when the scheduler was not granted.

select-challenge

(select-challenge identifier authoritative-zones available-methods)

Choose the challenge type for IDENTIFIER, fail-closed by topology: dns-01 when valis is authoritative for its zone AND the CA offers dns-01; otherwise a host-based method (tls-alpn-01, then http-01) the CA offers; otherwise SIGNAL unsatisfiable-identifier — the refusal raised before any order. A non-authoritative identifier never selects dns-01 (valis cannot publish into a zone it does not serve).

start-acme-manager

(start-acme-manager &key capabilities)

The :start thunk: capture the resolved CAPABILITIES alist into the module handle (no ambient globals), start the granted scheduler, re-derive the renewal schedule from mercer custody, and return the handle. Null-safe: with no scheduler granted (an unwired custody at dial-zero) it starts nothing and schedules nothing.

stop-acme-manager

(stop-acme-manager manager)

The :stop thunk: stop the granted scheduler behind MANAGER (idempotent). A no-op when MANAGER granted no scheduler.

Variables

*authoritative-zones-fn*

The seam returning the authoritative zone origins. Default reads ndb; rebound in cold selection tests to an explicit list.

*ca-account-contact*

The operator ACME account contact threaded to an order, or NIL when unset. It MUST be a non-NIL string at order time: mercer wraps the contact as "mailto:<contact>" unconditionally, so a NIL contact becomes the literal "mailto:NIL" that an ACME server (Pebble included) rejects. A configurable seam — the operator sets it to their account email; the module never fabricates one.

*ca-order-profile*

The ACME profile an order asks for, or NIL to take mercer's own default. A configurable seam the operator sets per target authority.

⚠ NIL does NOT mean no profile is sent. I had it written down the other way here until I placed an order and watched it. NIL sends mercer's own default, "tlsserver", and that is a name only Let's Encrypt advertises, so every other authority refuses the order before it reaches a challenge. Set this to a name the target authority advertises: Pebble, the local test authority, advertises "default" and "shortlived". Asking for no profile at all is not something this seam can express today.

*cert-custody-enumerator*

The seam enumerating certs in mercer custody as a list of plists (:cert-id .. :certificate .. :renew-fn ..), read by the renewal clock, the expiry belt and the STATUS line alike. Rebound in tests.

The default reads the custody store the operator configured for the edge, and NOTHING when none is configured. It deliberately declines the library default store: reaching for it would make a production seam depend on whatever leftover certificate happens to sit in a developer's state directory, and a node would schedule real renewals for a name it has never served.

*first-obtain-driver*

The seam driving an initial order's CA transport. Default: forward to ca-transport-obtain (the granted CA-transport capability). Rebound in cold tests to a capturing stub so obtain-initial-certificate's compose — the topology-grouped identifiers, the solver plist, the threaded contact/store/profile — is proven without a live CA, mirroring the renewal path's injectable seams.

*next-renewal-fn*

The seam computing a cert's next-renewal instant. Default: mercer next-renewal-instant (ARI when offered, else the one-third-life heuristic).

*obtain-store-builder*

The seam building an initial order's ACME custody store from a store-path. Default: %obtain-store, which primes the ffi-free ACME client (ensure-ffi-free-acme) and constructs the boomer cert-store. Rebound in cold tests to a stub returning a dummy store, so the flag-to-driver compose is proven without booting the ffi-free ACME client — that boot does a register-immutable-system "cl+ssl" whose load order is fragile once the real cl+ssl is already present in the image.

*renewal-failure-counter*

The seam reading a cert's consecutive-failure count for the backoff. Default: the durable row. Rebound in cold tests.

*renewal-recorder*

The seam recording a renewal outcome. Default: the durable renewal-health CAS. Rebound in cold tests to a capturing stub.

*tls-credential-reloader*

The seam that hot-swaps the live :443 listener's certificate after a successful renewal. Called with the renewed DOMAIN and its freshly-issued CHAIN and KEY; the default resolves the running public-HTTPS edge's shared credential cell by reference and swaps the pair in place (mercer's atomic reference store) so the next handshake serves the new cert with the listening socket never dropped. Late-resolved so the manager takes no load-time dependency on the edge module; rebound in cold tests to a capturing stub, so the success/failure branch is provable with no live listener and no CA.

+acme-manager-module-name+

The active-module registry name of the ACME manager.

Package valis/src/active/capability

Classes

active-capability

Base type for a seam-constructed capability object handed to an active module. Not directly instantiable (:constructor nil). Every subtype is a closed value: it carries only the authority it names and holds no ambient reference to a substrate global.

ca-transport-capability

The CA-transport egress capability. Carries a single OBTAIN closure wrapping mercer's obtain-certificate, defaulting the directory URL through the config production gate (resolve-acme-directory-url) so valis reaches the CA only via the grant and can never place a production order without the explicit opt-in. Holds no substrate global — the module drives it only through CA-TRANSPORT-OBTAIN.

dial-capability

The outbound-dial egress capability (the /net/dial and /net/dial/<scope> designations). Carries its DESIGNATION, the SCOPE read out of it by the same seam that decides on it (:EVERY-DESTINATION for the broad grant), and a single DIAL closure holding the grant that seam evaluates against. It holds only that closure, no substrate global and no socket and no address, so a module reaches the network through DIAL-THROUGH and nothing else.

A broad grant is by construction a general egress channel, correct for a person browsing and fully exfiltrating in the hands of a compromised process. Grant width should track what a module is doing now rather than everything it might one day need.

echo-capability

The trivial dial-zero granted capability: its sole behavior is to echo its argument (see ECHO-THROUGH). It captures no substrate global — DESIGNATION is a trust-neutral string, not a seam handle — so a module holding it can reach nothing beyond the echo.

listener-bind-capability

A transient public-listener bind grant (the /edge/listen/<port> designation). It carries its DESIGNATION, parsed PORT, and a BINDER closure of (host backlog) that performs the valis-owned usocket:socket-listen on PORT and returns the live listening socket — the capability's real body (see BIND-LISTENER). valis owns the bind; the responder handed the socket drives accept and never binds ambiently at all. BOUND stays nil at construction: holding the capability is the authority to bind, not a live socket — a socket exists only for the span BIND-LISTENER returns one and the responder closes it under unwind-protect.

scheduler-capability

The scheduler egress capability. Carries a fresh, UNSTARTED scheduler instance; the module owns its lifecycle through SCHEDULER-CAP-START / SCHEDULER-CAP-STOP and posts renewal tasks through SCHEDULER-CAP-POST. Construction spins no thread — a closed value with no ambient reference — so the scheduler is reached only as a granted capability, never a process-global.

zone-write-capability

The zone-write egress capability. Carries a PUBLISH and a RETRACT closure that wrap publish-/retract-transient-rrset-member, each supplying the LIVE fence generation at call time and running inside a pooled operator-state connection. It holds only these closures — no substrate global — so a module reaches the zone only through the two behaviors ZONE-WRITE-PUBLISH / ZONE-WRITE-RETRACT.

Conditions

capability-refused

Signalled when a capability is requested for a designation the grant-set does not name (:not-granted) or that the seam has no constructor for (:no-constructor). The refusal is by construction — a non-granted designation's constructor is never invoked.

Generic functions

capability-refused-designation

(capability-refused-designation condition)

Undocumented: this exported symbol needs a docstring.

capability-refused-reason

(capability-refused-reason condition)

Undocumented: this exported symbol needs a docstring.

Functions

active-capability-p

(active-capability-p object)

Undocumented: this exported symbol needs a docstring.

bind-listener

(bind-listener capability &key (host "0.0.0.0") (backlog 8))

Open the transient public listener CAPABILITY grants and return the live usocket listening socket. Performs the valis-owned usocket:socket-listen on the capability's granted port through its binder — valis owns the bind, so the responder that drives accept on the returned socket never calls socket-listen itself. HOST defaults to 0.0.0.0 so the CA can reach the responder during a real order (a test passes 127.0.0.1, or port 0 for an OS-assigned free port). The caller MUST close the returned socket on teardown, under unwind-protect — the transient bind lives only for the order's duration.

ca-transport-capability-designation

(ca-transport-capability-designation instance)

Undocumented: this exported symbol needs a docstring.

ca-transport-capability-p

(ca-transport-capability-p object)

Undocumented: this exported symbol needs a docstring.

ca-transport-obtain

(ca-transport-obtain capability identifiers challenge-solvers &rest keys)

Drive one certificate order for IDENTIFIERS with CHALLENGE-SOLVERS through CAPABILITY — the CA-transport authority. KEYS forwards obtain-certificate options (:account-contact :store :profile :skip-tls-verify, and :directory-url to override the config-gated default). Returns (values certificate-pem next-renewal-instant).

construct-capability

(construct-capability designation grant-set)

Construct the capability object for DESIGNATION, but ONLY if DESIGNATION is a member of GRANT-SET. A designation GRANT-SET does not name is refused fail-closed: signals CAPABILITY-REFUSED with reason :not-granted and NEVER looks up or invokes a constructor for it — the refusal is by construction, not a post-hoc check. Signals CAPABILITY-REFUSED with reason :no-constructor when DESIGNATION is granted but the seam has no constructor for it. Otherwise returns the constructed object.

dial-capability-designation

(dial-capability-designation instance)

Undocumented: this exported symbol needs a docstring.

dial-capability-p

(dial-capability-p object)

Undocumented: this exported symbol needs a docstring.

dial-capability-scope

(dial-capability-scope instance)

Undocumented: this exported symbol needs a docstring.

dial-scope

(dial-scope designation)

What DESIGNATION reaches: :EVERY-DESTINATION, the one destination its trailing segment names, or NIL when it is not a designation this file recognises.

The trailing segment carries the reach in the shape the listener-bind designation already established for a parameter carried in a designation, so an operator reading a grant-set sees what a dial grant reaches in the designation itself rather than having to look it up somewhere else.

An unrecognised designation answers NIL rather than being treated as a harmless unknown, because a designation nobody wrote a meaning for is exactly the shape a mistake takes.

This is the one place the rule is written. A second reading of the same string somewhere else would be a second rule, and the two would drift apart quietly on a string that decides where a principal may go.

dial-through

(dial-through capability destination port &rest keys)

Open a connection to DESTINATION at PORT through CAPABILITY, the outbound authority. KEYS forwards the verb's options (:type :family :source :deadline). Returns (values file-descriptor peer family); the caller owns the descriptor and its close from the moment this returns.

echo-capability-designation

(echo-capability-designation instance)

Undocumented: this exported symbol needs a docstring.

echo-capability-p

(echo-capability-p object)

Undocumented: this exported symbol needs a docstring.

echo-through

(echo-through capability value)

The echo capability's sole behavior: return VALUE unchanged. CAPABILITY holds no substrate handle, so this reaches nothing beyond its argument.

granted-designations

(granted-designations vouch-token)

The list of designations VOUCH-TOKEN grants — read off the SAME verified token, no second trust check. Mirrors the module-admission discipline of reading grant directives from the token the verifier already validated; revocation and fence enforcement stay inside the verifier, never duplicated here.

listen-bind-designation

(listen-bind-designation port)

Build the reserved listener-bind designation edge/listen/<PORT>. The convention is collision-safe: build-base-view never materializes /edge/listen into a mountable subtree, so the seam interprets the string as a bind grant rather than a namespace right.

listener-bind-capability-bound

(listener-bind-capability-bound instance)

Undocumented: this exported symbol needs a docstring.

listener-bind-capability-designation

(listener-bind-capability-designation instance)

Undocumented: this exported symbol needs a docstring.

listener-bind-capability-p

(listener-bind-capability-p object)

Undocumented: this exported symbol needs a docstring.

listener-bind-capability-port

(listener-bind-capability-port instance)

Undocumented: this exported symbol needs a docstring.

make-ca-transport-capability

(make-ca-transport-capability designation &optional dial-capability)

Construct the CA-transport capability for DESIGNATION. Its obtain closure calls mercer's obtain-certificate (reached by symbol-call so no drakma is pulled until an order actually runs), defaulting DIRECTORY-URL to the config-gated resolve-acme-directory-url (production is unreachable without VALISACMEPRODUCTION), and forwarding only the caller-supplied keys so mercer's own defaults stand.

Every request the order makes goes out through the outbound seam, under DIAL-CAPABILITY when one was handed in and otherwise under the authority this node's own configuration names. The binding lasts exactly as long as the order: scoped, so the authority is provably on the path that was granted it, and so the tests and the proof script that legitimately stub the request seam are not captured by an order running somewhere else in the image.

make-dial-capability

(make-dial-capability designation &optional grant-hash)

Construct the outbound-dial capability for DESIGNATION.

GRANT-HASH is what the owner names when withdrawing this grant. Supplying it is what lets a withdrawal reach decisions already taken for the grant; a capability built without one is evaluated afresh on every dial, which is slower and never less safe. The capability-constructor table calls this with the designation alone, so a caller that holds the hash of the token the designation was read off passes it here.

make-echo-capability

(make-echo-capability designation)

Construct the trivial echo capability for DESIGNATION — a closed object whose only behavior is ECHO-THROUGH and whose only state is the trust-neutral designation string.

make-listener-bind-capability

(make-listener-bind-capability designation)

Construct the listener-bind capability for DESIGNATION (a /edge/listen/<port> string) with its REAL body: a valis-owned socket-listen binder over the granted port. The returned capability carries its designation, parsed port, and a binder closure that performs usocket:socket-listen when the responder calls BIND-LISTENER — valis owns the bind, so the responder drives accept on the handed socket and never calls socket-listen itself, and no bind happens ambiently.

make-scheduler-capability

(make-scheduler-capability designation)

Construct the scheduler capability for DESIGNATION over a fresh, unstarted scheduler. No thread runs until the module calls SCHEDULER-CAP-START.

make-zone-write-capability

(make-zone-write-capability designation)

Construct the zone-write capability for DESIGNATION. Its publish/retract closures wrap publish-/retract-transient-rrset-member (reached by symbol-call), each folding in the live store generation (%live-store-generation, Pitfall 6) and running inside a pooled operator-state connection (%call-in-operator-state). The caller supplies (origin owner type ttl rdata) — never the generation, which the capability always reads current.

mint-active-grant

(mint-active-grant designations)

Mint an owner-rooted capability token carrying one mount-directive per string in DESIGNATIONS (the module's egress grant-set), signed by the live owner custody (factotum-custody). Mirrors the module-admission vouch mint but carries egress designations rather than a single :admit directive: the SEAM interprets each designation (a listener-bind, an internal seam), so the rights are a uniform :mount placeholder over the closed set. Draws a fresh OS-entropy nonce per mint, signs the draft's canonical bytes, and stamps the canonical hash as SHA-256 of (canonical-bytes || signature) — the same minter contract verify-token-chain reconstructs. Returns nil fail-closed when no custody is wired — no grant is honored without a live owner.

register-capability-constructor

(register-capability-constructor designation constructor)

Install CONSTRUCTOR (a function of one argument, the designation string, returning a capability object) under DESIGNATION. Idempotent: re-registering the same designation replaces the constructor. Returns CONSTRUCTOR.

resolve-granted-capabilities

(resolve-granted-capabilities grant-set)

Resolve GRANT-SET (a list of granted designation strings, e.g. from GRANTED-DESIGNATIONS on the minted vouch) into an alist of (designation . capability-object). Constructs ONLY designations that are BOTH in GRANT-SET AND have a seam constructor; a granted designation with no constructor is omitted. A designation NOT in GRANT-SET is never iterated and never constructed — the module receives exactly this alist and can reach no substrate seam absent from it. This is the fail-closed-by-construction guarantee: egress is bounded by which objects were built, not by a runtime allowlist a caller could bypass.

scheduler-cap-post

(scheduler-cap-post capability fire-at thunk)

Post THUNK to run at FIRE-AT (an absolute universal-time) on the scheduler behind CAPABILITY. THUNK returns its own next-fire time (NIL one-shot, or a universal-time to reschedule — an ARI instant or a backoff delay). Returns the scheduled task.

scheduler-cap-start

(scheduler-cap-start capability)

Spin the owned scheduler thread behind CAPABILITY (idempotent). Returns the scheduler.

scheduler-cap-stop

(scheduler-cap-stop capability)

Stop and join the owned scheduler thread behind CAPABILITY (idempotent).

scheduler-capability-designation

(scheduler-capability-designation instance)

Undocumented: this exported symbol needs a docstring.

scheduler-capability-p

(scheduler-capability-p object)

Undocumented: this exported symbol needs a docstring.

scheduler-capability-scheduler

(scheduler-capability-scheduler instance)

Undocumented: this exported symbol needs a docstring.

zone-write-capability-designation

(zone-write-capability-designation instance)

Undocumented: this exported symbol needs a docstring.

zone-write-capability-p

(zone-write-capability-p object)

Undocumented: this exported symbol needs a docstring.

zone-write-publish

(zone-write-publish capability origin owner type ttl rdata)

Publish the transient rrset member (OWNER TYPE TTL RDATA) into the zone at ORIGIN through CAPABILITY — the zone-write authority carrying the live fence generation. Returns (values resolved-serial changed-p).

zone-write-retract

(zone-write-retract capability origin owner type rdata)

Retract the transient rrset member (OWNER TYPE RDATA) from the zone at ORIGIN through CAPABILITY — the zone-write authority carrying the live fence generation. Returns (values resolved-serial changed-p).

Variables

*capability-constructors*

Designation string -> constructor function of one argument (the designation) returning a closed capability object. The seam alone owns this table: a designation absent from it (and not matching a reserved prefix) has no constructor and can never be built, so it can never be handed to a module.

+ca-transport-designation+

The reserved designation of the CA-transport egress capability: the authority to drive one mercer obtain-certificate order, so valis reaches the CA only through the grant (and only the config-gated directory URL).

+dial-designation+

The designation of a grant that reaches every destination.

+dial-prefix+

The prefix of a grant whose reach is narrowed by its trailing segment, in the shape the listener-bind designation already established for a parameter carried in a designation.

+scheduler-designation+

The reserved designation of the scheduler egress capability: the authority to post/start/stop the time-based event loop that drives the renewal clock, so the scheduler is reached only as a granted capability, never a process-global.

+zone-write-designation+

The reserved designation of the zone-write egress capability: the authority to publish/retract a transient rrset member (the dns-01 challenge TXT) into the live authoritative zone, carrying the live fence generation.

Package valis/src/active/cert-watch

Functions

check-cert-expiry

(check-cert-expiry &key (now (get-universal-time)))

The independent cert-expiry belt: enumerate the certs in mercer custody and, for each whose renewal instant has already passed (the ACME manager should have renewed it but the leaf is still in custody) AND whose last renewal attempt is older than one backoff-cap interval (so a cert the manager is actively retrying does not false-alarm), emit an ERROR cert.expiry-imminent event carrying substrate facts only — the cert-id and its whole days-to-expiry, never key bytes. Returns the list of flagged cert-ids.

Kept strictly OFF the watchdog path: this never pings the watchdog and never feeds serving-path-live-p. A silently un-renewed leaf is an operator-visible ERROR to surface, not a service-restart condition.

Variables

*cert-days-to-expiry-fn*

Seam returning a cert's whole days-to-expiry. Default: mercer's PEM validity parse. Rebound in tests.

*cert-last-attempt-fn*

Seam returning a cert's last renewal-attempt universal-time, or NIL when none is recorded. Default: the durable renewal-health row. Rebound in tests.

Package valis/src/active/controller

Functions

retire-active-module

(retire-active-module name)

Stop and forget the live active entry whose spec name matches NAME (normalized via STRING), and remove NAME from active-modules so a later start-actives will not start a now-deleted module - the per-module drain the delete-hook calls, mirroring retire-edge-adapter (drain the live handle, then unregister).

Returns T if a live entry was stopped, NIL if none was live. Signals RETIREMENT-INCOMPLETE when the module's :stop did not return: the handle is still running, so the entry STAYS in active-entries and a second retire attempts it again. The unregister is attempted either way, so a module that could not be stopped is at least not started again by a later start-actives.

start-actives

(start-actives &key (modules (active-modules)))

Start every registered active module (default (active-modules), deterministic STRING<-sorted order) AFTER the edge is up. For EACH spec: mint its grant-set, read the granted designations back off the verified token, resolve them to capability objects, and hand ONLY that capability alist to :start; record the (SPEC . HANDLE) in active-entries. Fail-closed: the whole sequence is wrapped in an unwind-protect that, on a mid-sequence :start error, stops exactly the modules already started, in reverse start order, and lets the error re-signal — no half-started fleet, no live entry left behind. Returns the started (SPEC . HANDLE) entries in start order.

stop-actives

(stop-actives)

Tear every started active module down in reverse start order — active-entries carries the most-recently-started module at the head, so a head-to-tail walk IS reverse start order — calling each spec's :stop thunk on its handle, each step error-isolated so one failure cannot strand the rest, then clear active-entries. Idempotent: a no-op on an empty registry. This is the FIRST teardown call on every boot unwind, stopping actives before the edge.

Variables

*active-entries*

The supervisor's single-owner ordered record of started active modules — a list of (SPEC . HANDLE) with the most-recently-started module at the head, so a head-to-tail walk is reverse start order. start-actives pushes each module it successfully starts; stop-actives tears the whole list down in reverse and clears it; retire-active-module removes one entry by name. Empty when no active module is running.

Package valis/src/active/scheduler

Classes

scheduler

A single-owner time-based event loop. One owned thread sleeps until the nearest task deadline, runs every due task, and re-enqueues each by the next-fire time its thunk returns. LOCK guards QUEUE and the lifecycle flags; WAKEUP wakes the sleeping thread when a nearer task is posted or a stop is requested (no busy-wait). QUEUE is time-ordered ascending by (FIRE-AT, SEQ). Reached only as a granted capability, never a process-global.

Functions

make-scheduler

(make-scheduler)

Construct an inert scheduler. No thread exists and no task fires until START-SCHEDULER spins the owned thread. Reached by an active module only as a granted capability, never a process-global.

post-task

(post-task scheduler fire-at thunk)

Enqueue THUNK to run at FIRE-AT (an absolute universal-time) on SCHEDULER's owned thread and wake the thread so a nearer deadline is honored immediately. THUNK is called with no arguments and must return its own next-fire universal-time — NIL to run once, or a universal-time to reschedule (a value already in the past fires on the next loop turn). Returns the scheduled-task.

scheduler-alive-p

(scheduler-alive-p scheduler)

True while SCHEDULER's owned thread is running and has not been stopped.

start-scheduler

(start-scheduler scheduler)

Spin SCHEDULER's single owned thread and return SCHEDULER. Idempotent: starting an already-running scheduler is a no-op. The thread runs until STOP-SCHEDULER.

stop-scheduler

(stop-scheduler scheduler)

Stop SCHEDULER's owned thread and join it cleanly (no busy-wait). Idempotent: stopping an already-stopped scheduler is a benign no-op. Returns no values.