valis / Reference / API reference

Plugins - API reference

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

Package valis/src/plugin/active-module

Classes

active-module-spec

One registered active (resident) module. NAME is the module's name (the registry key material). START is a thunk that starts the module and returns a handle the seam owns; STOP is a thunk that tears the handle down; ALIVE-P is an optional thunk the seam polls for liveness (NIL when the option omits it). GRANTS is the list of egress-designation strings the module requests — carried verbatim as trust-neutral data, resolved into capabilities downstream, not here. CONTRACT-VERSION is the seam contract version admitted at registration.

Conditions

active-module-version-mismatch

Signalled by register-active-module when a module declares a contract version outside supported-active-module-contract-versions. The registry is left unchanged — the refusal happens before any setf gethash.

Functions

active-module-spec-alive-p

(active-module-spec-alive-p instance)

Undocumented: this exported symbol needs a docstring.

active-module-spec-contract-version

(active-module-spec-contract-version instance)

Undocumented: this exported symbol needs a docstring.

active-module-spec-grants

(active-module-spec-grants instance)

Undocumented: this exported symbol needs a docstring.

active-module-spec-name

(active-module-spec-name instance)

Undocumented: this exported symbol needs a docstring.

active-module-spec-start

(active-module-spec-start instance)

Undocumented: this exported symbol needs a docstring.

active-module-spec-stop

(active-module-spec-stop instance)

Undocumented: this exported symbol needs a docstring.

active-modules

(active-modules)

Return the registered ACTIVE-MODULE-SPECs in a deterministic order, sorted by name via STRING<. The stable order is what gives the boot supervisor a stable start/stop iteration order across runs.

register-active-module

(register-active-module &key name start stop alive-p grants (contract-version +active-module-contract-version+))

Register an active module under NAME. START/STOP/ALIVE-P are the lifecycle thunks the seam owns (ALIVE-P may be NIL); GRANTS is the module's requested egress-designation list, stored verbatim. Runs the fail-closed version check FIRST: if CONTRACT-VERSION is not in supported-active-module-contract-versions it signals ACTIVE-MODULE-VERSION-MISMATCH and adds NO entry — the refuse-before-act discipline leaves no partial registry state. Otherwise builds a fresh ACTIVE-MODULE-SPEC and stores it under (STRING NAME). IDEMPOTENT: re-registering the same name REPLACES the spec with no error, absorbing the compile-then-load double-fire of a module's define-module. Returns the spec.

unregister-active-module

(unregister-active-module name)

Remove the module registered under NAME (normalized via STRING). Returns T if a module was present and removed, NIL otherwise.

Variables

*active-modules*

Module name -> ACTIVE-MODULE-SPEC. The key is the name normalized via STRING, so :acme, "acme", and 'acme collapse to the one key "ACME". A resident module installs onto this registry on load via the :active-module define-module option. This is the registry the boot supervisor iterates to start/poll/stop each resident module; valis names no concrete module.

*supported-active-module-contract-versions*

The contract versions register-active-module admits. A module declaring a version outside this set is refused fail-closed — no silent skew.

Constants

+active-module-contract-version+

The active-module seam contract version valis currently exposes. With the registry and the register function, this is the surface valis signals a resident module over the seam.

Package valis/src/plugin/admit-module

Functions

admit-module

(admit-module system root files vouch &key (loader (function load-system)))

Admit and load the locally-present protocol module SYSTEM only when VOUCH is an owner-rooted authority granting :admit over the module's content hash.

SYSTEM is the ASDF system designator handed to the loader. ROOT and FILES are the module root and its .asd+source pathname list, content-addressed by module-bundle-score to form the /module/<hash> the vouch must name. VOUCH is the held bearer credential (a capability-token object or a valis:/token: string) and arrives as an explicit argument.

Returns (values t nil) on admission — the loader ran on SYSTEM. Returns (values nil reason-string) on refusal — the loader is NEVER invoked, so a refused module never compiles, loads, or self-registers (load == registration via the :edge-adapter option), leaving no partial module state.

LOADER defaults to #'asdf:load-system, so an absent :loader argument is byte-for- byte today's behavior; it exists only as a test seam so the load-once invariant can be asserted directly with a counting stub. The default must stay #'asdf:load-system.

The entire body is wrapped in a handler-case; any unhandled condition becomes a (values nil reason-string) return so this chokepoint is fail-closed. The reserved module/<64-hex> designation cannot collide with a real mountable path: build-base-view materializes only the owner canonical frame (/proto /bus /id /cap /pub /edge /ctl), the anonymous /pub floor, or an empty view — it never materializes /module…, so a vouch designation can never name a live subtree.

Package valis/src/plugin/condense-modules

Conditions

module-unreachable

Signalled during Pass 2 when a record's source cannot be materialized at the destination or its re-derived module-bundle-score does not equal the recorded score. A module-tier fault kept distinct from the store-tier module-manifest- corrupt: the whole condensation aborts fail-closed (no partial module set) before any admit-module call.

Generic functions

module-unreachable-system

(module-unreachable-system condition)

Undocumented: this exported symbol needs a docstring.

Functions

condense-modules

(condense-modules store root-entry &key vouch-locator loader puller destination-root)

Stand the destination's module set up from the durable module manifest under ROOT-ENTRY in STORE — fail-closed, all-or-nothing.

VOUCH-LOCATOR is a (SCORE) -> vouch-or-nil thunk: the vouch a module's /module/<score> must carry, located against live revocation/fence state in production (the re-mint posture) and a test mint in the suite. A nil return for any record's score aborts the whole condensation before any load.

LOADER is admit-module's :loader test seam (defaults through admit-module to asdf:load-system); PULLER overrides module-puller for this call; DESTINATION-ROOT is the absolute on-disk prefix the records' relative source paths resolve against.

Returns (values count loaded-systems) on success — the count of admitted modules and the list of their system-names in canonical order — once EVERY record admits. On any abort returns (values nil reason) and leaves edge-adapters exactly as it was on entry (no partial module set), or signals module-unreachable when a record cannot be reached / re-derived in Pass 2.

Pass 1 read-module-manifest (fail-closed — a corrupt manifest aborts here). Pass 2 resolve + reachability + vouch precheck over ALL records, NO loads. Pass 3 ordered admit-module per record on the Pass-2 resolved pair; restore edge-adapters from the entry snapshot on the first refusal.

condense-modules routes every module through admit-module and NEVER calls asdf:load-system directly: the gate is structurally in front of the loader. admit-module's own in-gate re-hash over the same resolved pair is intentional defense-in-depth (the gate independently re-verifies the content it is about to load), not a redundant resolution.

local-store-puller

(local-store-puller score record destination-root)

The default local-store pull/resolve: the bytes are already on disk at the recorded relative paths under DESTINATION-ROOT, so this is exactly the nil-seam resolution surfaced as a puller value. Returns (values root files); SCORE is ignored (the bytes are not fetched, only located). Installed into module-puller by a wiring layer when a caller wants the seam non-nil; behaviorally identical to leaving the seam nil.

Variables

*module-puller*

The module pull/resolve transport seam, or NIL.

When NIL, condense-modules resolves a record's RELATIVE source list against DESTINATION-ROOT (the bytes are already on disk at the recorded relative paths — today's single-instance case). When non-nil, it is a function of (SCORE RECORD DESTINATION-ROOT) returning (values ROOT FILES) — the resolved, ABSOLUTE (root files) locator for the module named by SCORE — or signalling module-unreachable when the bytes cannot be obtained.

This is the seam that keeps the pull transport-agnostic: a future IPFS/libp2p transport rebinds module-puller to materialize the bytes from a content- addressed network WITHOUT reshaping the module record (the IPFS gate stays open). The default is NIL so a unit test can drive the local on-disk path explicitly; local-store-puller is the local-fetch helper a wiring layer installs into the seam.

Package valis/src/plugin/dns-adapter

Classes

dns-adapter-spec

One registered DNS adapter. NAME is the adapter's name (the registry key material). HANDLER is a function of a decoded query that speaks the wire and returns a response designator; the wire engine binds it. CONTRACT-VERSION is the seam contract version the binding engine declared at registration — the value the fail-closed register-time check admitted. SOURCE is the raw zone-data-source the serving handler was bound over (in production a pg-zone-source), retained so a caller that already holds the admitted handler can reach the same underlying zone records — the AXFR emit path streams the zone directly off it. NIL for a registration that carried no source (the module self-registration path, which binds only a deferred-resolution handler).

Conditions

dns-adapter-version-mismatch

Signalled by register-dns-adapter when a binding engine declares a contract version outside supported-dns-contract-versions. The registry is left unchanged — the refusal happens before any setf gethash.

Functions

dns-adapter-spec-contract-version

(dns-adapter-spec-contract-version instance)

Undocumented: this exported symbol needs a docstring.

dns-adapter-spec-handler

(dns-adapter-spec-handler instance)

Undocumented: this exported symbol needs a docstring.

dns-adapter-spec-name

(dns-adapter-spec-name instance)

Undocumented: this exported symbol needs a docstring.

dns-adapter-spec-source

(dns-adapter-spec-source instance)

Undocumented: this exported symbol needs a docstring.

dns-adapters

(dns-adapters)

Return the registered DNS-ADAPTER-SPECs in a deterministic order, sorted by name via STRING<. The stable order is what gives the dispatcher a stable iteration order across runs.

register-dns-adapter

(register-dns-adapter &key name handler source (contract-version +dns-adapter-contract-version+))

Register a DNS adapter under NAME with HANDLER declaring CONTRACT-VERSION. Runs the fail-closed version check FIRST: if CONTRACT-VERSION is not in supported-dns-contract-versions it signals DNS-ADAPTER-VERSION-MISMATCH and adds NO entry — the refuse-before-act discipline leaves no partial registry state. Otherwise builds a fresh DNS-ADAPTER-SPEC and stores it under (STRING NAME). IDEMPOTENT: re-registering the same name REPLACES the spec with no error, absorbing the compile-then-load double-fire of a module's define-module and mirroring REGISTER-PROTOCOL :replace. HANDLER is a function of a decoded query returning a response designator. SOURCE is the optional raw zone-data-source the handler was bound over, retained on the spec so a serving path can reach the same zone records the handler answers from (the AXFR emit path streams the zone directly off it); NIL on the module self-registration path, which carries no source. Returns the spec.

unregister-dns-adapter

(unregister-dns-adapter name)

Remove the adapter registered under NAME (normalized via STRING). Returns T if an adapter was present and removed, NIL otherwise.

Variables

*dns-adapters*

Adapter name -> DNS-ADAPTER-SPEC. The key is the name normalized via STRING, so :dns, "dns", and 'dns collapse to the one key "DNS" (STRING on a symbol yields its symbol-name, on a string yields itself). A protocol module installs onto this registry on load via the :dns-adapter module option. This is the registry the dispatcher iterates to find the adapter that answers a decoded query; valis names no concrete adapter.

*supported-dns-contract-versions*

The contract versions register-dns-adapter admits. A binding engine declaring a version outside this set is refused fail-closed — no silent skew with the wire engine.

Constants

+dns-adapter-contract-version+

The DNS adapter seam contract version valis currently exposes. With the registry and the register function, this is the surface valis signals the out-of-tree wire engine over the bus.

Package valis/src/plugin/edge-adapter

Classes

edge-adapter-spec

One registered edge adapter. NAME is the adapter's name (the registry key material). CONSTRUCTOR is a function of (&key port budget) returning a fresh protocol whose PROTOCOL-PORTS reflect the port override (or the adapter's own default when PORT is NIL); the adapter owns binding its own …-port special — nothing here names an adapter's port variable. BUDGET is the adapter's default per-port concurrent-connection budget (or NIL to take the controller's default).

Functions

edge-adapter-spec-budget

(edge-adapter-spec-budget instance)

Undocumented: this exported symbol needs a docstring.

edge-adapter-spec-constructor

(edge-adapter-spec-constructor instance)

Undocumented: this exported symbol needs a docstring.

edge-adapter-spec-name

(edge-adapter-spec-name instance)

Undocumented: this exported symbol needs a docstring.

edge-adapters

(edge-adapters)

Return the registered EDGE-ADAPTER-SPECs in a deterministic order, sorted by name via STRING<. The stable order is what gives the controller a stable port-bind order across runs.

register-edge-adapter

(register-edge-adapter &key name constructor budget)

Register an edge adapter under NAME with CONSTRUCTOR and BUDGET. Builds a fresh EDGE-ADAPTER-SPEC and stores it under (STRING NAME). IDEMPOTENT: re-registering the same name REPLACES the spec with no error — this absorbs the compile-then-load double-fire of a module's define-module and mirrors REGISTER-PROTOCOL :replace. CONSTRUCTOR is a function of (&key port budget). Returns the spec.

unregister-edge-adapter

(unregister-edge-adapter name)

Remove the adapter registered under NAME (normalized via STRING). Returns T if an adapter was present and removed, NIL otherwise.

Variables

*edge-adapters*

Adapter name -> EDGE-ADAPTER-SPEC. The key is the name normalized via STRING, so :http, "http", and 'http collapse to the one key "HTTP" (STRING on a symbol yields its symbol-name, on a string yields itself). A protocol module installs onto this registry on load via the :edge-adapter module option and is retired by the controller's delete-hook. This is the registry that replaces the edge controller's hard-coded adapter list; the controller iterates EDGE-ADAPTERS and binds a real port per spec.

Package valis/src/plugin/mail-adapter

Classes

mail-adapter-spec

One registered mail adapter. NAME is the adapter's name (the registry key material). DELIVER is a function called with a queue entry that speaks the wire and returns one of :delivered / :deferred / :bounced and mutates nothing else; the driver, not the adapter, records the disposition. Inbound landing is the valis-exported LAND-MESSAGE the adapter calls into, so the spec carries no inbound-handler slot.

Functions

mail-adapter-spec-deliver

(mail-adapter-spec-deliver instance)

Undocumented: this exported symbol needs a docstring.

mail-adapter-spec-name

(mail-adapter-spec-name instance)

Undocumented: this exported symbol needs a docstring.

mail-adapters

(mail-adapters)

Return the registered MAIL-ADAPTER-SPECs in a deterministic order, sorted by name via STRING<. The stable order is what gives the drain driver a stable iteration order across runs.

register-mail-adapter

(register-mail-adapter &key name deliver)

Register a mail adapter under NAME with DELIVER. Builds a fresh MAIL-ADAPTER-SPEC and stores it under (STRING NAME). IDEMPOTENT: re-registering the same name REPLACES the spec with no error — this absorbs the compile-then-load double-fire of a module's define-module and mirrors REGISTER-PROTOCOL :replace. DELIVER is a function called with a queue entry, returning a disposition keyword. Returns the spec.

unregister-mail-adapter

(unregister-mail-adapter name)

Remove the adapter registered under NAME (normalized via STRING). Returns T if an adapter was present and removed, NIL otherwise.

Variables

*mail-adapters*

Adapter name -> MAIL-ADAPTER-SPEC. The key is the name normalized via STRING, so :smtp, "smtp", and 'smtp collapse to the one key "SMTP" (STRING on a symbol yields its symbol-name, on a string yields itself). A protocol module installs onto this registry on load via the :mail-adapter module option. This is the registry the outbound drain driver iterates to find the adapter that delivers a relay entry; valis names no concrete adapter.

Package valis/src/plugin/module-admission

Functions

module-admitted-p

(module-admitted-p score vouch)

Predicate form of verify-module-vouch: return just the boolean admission decision for callers that do not need the refusal reason. Fail-closed — any refusal or signalled condition reads as NIL.

verify-module-vouch

(verify-module-vouch score vouch)

Decide whether VOUCH admits the module whose content SCORE is the given 32-byte vector. Returns (values t nil) when an owner-rooted, unrevoked, unfenced authority grants :admit over exactly /module/<score-as-64-hex>; otherwise (values nil reason-string).

VOUCH is the held bearer credential, in any of the carrier forms the cap verify path accepts: a capability-token object, a "valis:""name:" bearer name string, or a "token:" serialized-token string. The trust check rides verify-token-chain / verify-capability-name-sig against the owner root and the shared revocation store — no parallel trust path, no second revocation check.

Fail-closed: any signalled condition becomes (values nil "<message>"); a refusal always carries a reason and never a bare nil, and no signal escapes.

Package valis/src/plugin/module-bundle

Functions

module-bundle-designation

(module-bundle-designation root files)

Compute the /module/<64-hex> designation for the module rooted at ROOT with the given .asd and source FILES — module-bundle-score then module-designation.

module-bundle-score

(module-bundle-score root files)

Content-address the module rooted at ROOT whose .asd and source FILES are the given pathname list, returning a 32-byte SHA-256 score.

Each file's path is taken relative to ROOT; the files are framed in canonical order — sorted by that relative path — so on-disk discovery order does not change the score. Each frame is u32-BE len(path) ‖ path ‖ u32-BE len(bytes) ‖ bytes with raw file content; the fixed-width prefixes make the framing resistant to partitioning collisions. The concatenated stream is digested once through store-block-digest — the store's single hash seam — so the module score shares one algorithm with the block store and the capability hashes.

module-designation

(module-designation score)

Render a 32-byte SCORE as its /module/<64-hex> designation — the path a vouch grants :admit over. The hex is the full-width, lowercase 64-character block name via score->name; never truncated.

Package valis/src/plugin/module-class

Classes

module-inferred-system

The :class a protocol module's .asd names. It is simultaneously a modularize VIRTUAL-MODULE and an ASDF PACKAGE-INFERRED-SYSTEM: ASDF derives the component graph from each file's defpackage :import-from, and modularize's module lifecycle applies to the resulting system. Superclass precedence is VIRTUAL-MODULE before PACKAGE-INFERRED-SYSTEM — the cold-verified order from spike 004; both are asdf:system subclasses so the combined CPL is coherent with no metaclass conflict. valis defines and exports this class; a protocol module sets :class "valis/src/plugin/module-class:module-inferred-system".

Package valis/src/plugin/social-admission

Functions

query-reachable

(query-reachable vouch start-did &rest traversal-args)

The /social-gated entry point to the social-graph traversal: verify VOUCH grants :read over /social, and only then run the recursive-CTE traversal from START-DID (forwarding TRAVERSAL-ARGS — e.g. :rel-type, :max-depth — to traverse-reachable). Returns the reachable-DID list on success; (values nil reason-string) when the vouch does not authorize the read.

This is the ONLY caller-facing entry to the UNAUTHENTICATED traverse-reachable primitive. Fail-closed: without a valid /social :read vouch the traversal never runs — the raw primitive is never reached, so a refused query touches no graph data.

verify-social-vouch

(verify-social-vouch vouch)

Decide whether VOUCH authorizes a social-graph read. Returns (values t nil) when an owner-rooted, unrevoked, unfenced authority grants :read over exactly the /social designation; otherwise (values nil reason-string).

VOUCH is the held bearer credential, in any of the carrier forms the cap verify path accepts: a capability-token object, a "valis:""name:" bearer name string, or a "token:" serialized-token string. The trust check rides verify-token-chain / verify-capability-name-sig against the owner root and the shared revocation store — no parallel trust path, no second revocation check.

Fail-closed: any signalled condition becomes (values nil "<message>"); a refusal always carries a reason and never a bare nil, and no signal escapes. An absent (nil) vouch is refused fail-closed — the query is never ungated.

Variables

+social-designation+

The dedicated capability designation that gates social-graph reads. A /social :read grant is the sovereignty boundary for the social axis — independently grantable and revocable, never an ambient operator-wide power and never piggybacked on a /proto or /names grant. The gate matches this designation EXACTLY (string=, not a prefix), so no broader subtree grant can satisfy it.