C Stable API

Rulesets

Select and identify policies without exposing parsed ruleset structures.

A ruleset is the logical program that the solver evaluates. The stable C API does not expose a ruleset_t, parsed rule array, or mutable symbol table. It loads source into an opaque maelys_datalog_policy_t * and prepares one selected policy in an opaque session. This page maps the ruleset concept to those public operations.

Types

Used from other pages

These types are defined on the linked pages; this page uses them in the roles below.

TypeUse on this pageDefined in
maelys_datalog_policy_tInput handle for counting, identifying and releasing policies.Manifests

Functions

FunctionPurpose
maelys_datalog_policy_count()Find the valid policy indices.
maelys_datalog_policy_fingerprint()Identify the loaded set independently of request facts.
maelys_datalog_policy_free()Release the loaded set after preparing the sessions that need it.

Load an opaque policy set

Choose inline source or a manifest after registering the domain. Both loaders return the same opaque policy-handle type. Inline source produces one policy, so index 0 is valid. A manifest may contain multiple enabled policies: count them before selecting one.

C · function
Count loaded policies
maelys_datalog_status_t
maelys_datalog_policy_count(
const maelys_datalog_policy_t * policy,
size_t * out_count
);
Reads how many policies belong to a loaded set, so the application can choose a valid policy index when creating a session.
Arguments
policyconst maelys_datalog_policy_t *
Opaque handle returned by a successful loader.
out_countsize_t *
Receives the number of selectable policies in this handle.
Return value
maelys_datalog_status_t

MAELYS_DATALOG_STATUS_OK on success; otherwise a fail-closed public status.

CODE
size_t count = 0;
maelys_datalog_status_t status = maelys_datalog_policy_count(policy, &count);

policy_count() does not expose the rules of a policy or combine the policies. It only gives the number of valid indices. session_create(policy, index, &session) selects exactly one of them. Two sessions can select different indices from the same handle, and each evaluates only its selected policy. See solving for their lifetime and result leases.

Example — document access

The inline load of documents.main on the manifest page contains one ruleset. Count before selecting its index; the handle does not expose or permit editing the parsed rules.

CODE
size_t count = 0u;
maelys_datalog_status_t status = maelys_datalog_policy_count(policy, &count);
if (status != MAELYS_DATALOG_STATUS_OK || count != 1u) {
    /* Loading failed or the expected policy is absent: deny. */
}
maelys_datalog_session_t *session = NULL;
status = maelys_datalog_session_create(policy, 0u, &session);

Index 0 selects documents.main from this one-policy inline handle, not the first predicate or the first rule. The same selected policy accepts the seven request facts on Runtime EDB.

Identity and ownership

A fingerprint answers whether two loaded policy sets have the same canonical identity; it does not include request facts.

C · function
Fingerprint the loaded set
maelys_datalog_status_t
maelys_datalog_policy_fingerprint(
const maelys_datalog_policy_t * policy,
char * out_fingerprint
);
Reads the identity of the complete loaded policy set. Use it to distinguish policy sets, rather than the execution configuration of a session.
Arguments
policyconst maelys_datalog_policy_t *
Opaque loaded policy set.
out_fingerprintchar *
Caller-owned buffer for its canonical fingerprint.
Return value
maelys_datalog_status_t

MAELYS_DATALOG_STATUS_OK on success; otherwise a fail-closed public status.

CODE
char fingerprint[MAELYS_DATALOG_PUBLIC_FINGERPRINT_BYTES];
maelys_datalog_status_t status = maelys_datalog_policy_fingerprint(
    policy, fingerprint);

The loaded-set fingerprint and a session's fingerprint answer different questions: the former identifies the loaded policy authority, while maelys_datalog_session_fingerprint() identifies the prepared selection. maelys_datalog_session_execution_fingerprint() additionally binds the backend, execution options, and size profile; runtime request facts are not part of that identity. Use the returned identity that matches the decision you need to attest.

After successful session creation, that session owns its prepared state. Release the loaded set when no new session needs it:

C · function
Release the loaded policy set
maelys_datalog_status_t
maelys_datalog_policy_free(
maelys_datalog_policy_t * policy
);
Releases a loaded policy-set handle when the application no longer needs it for creating sessions.
Arguments
policymaelys_datalog_policy_t *
Loaded set to release after preparing any required sessions.
Return value
maelys_datalog_status_t

Returns OK when the handle is released; an invalid handle or state returns an error.

CODE
maelys_datalog_status_t status = maelys_datalog_policy_free(policy);
policy = NULL;

Free each result before its session. The opaque handles do not permit direct modification of parsed rules after loading.

Loading failure is not a partial ruleset

Loader errors can fill maelys_datalog_diagnostic_t with a source location and a corrective hint. They publish no partial policy handle. A malformed source, undeclared predicate, forbidden source atom, or invalid manifest must be fixed and loaded again; the caller cannot repair the opaque handle in place. See stable errors.