orchestrata_ultimate.governance.volk_facts
Reference › orchestrata_ultimate › governance › volk_facts
The Prolog goals that make a volk operational. The governance gate allows a volk to act only when the facts that define volk_operational/1 hold for its alias, and this module builds the goal strings that assert and retract them. It imports nothing from the project; prolog_client and prolog_gate run the goals through their own assert_volk_operational, retract_volk_operational and set_volk_active methods.
quote_atom quotes an alias as a Prolog atom. assert_goals(alias) returns, for each positive operational fact, a retractall followed by an assertz in the governance module, so registering the same alias twice leaves one clause (the docstring says a duplicate would otherwise keep the gate open after deregistration), and a retractall for each blocking fact. retract_goals(alias) returns the goals that remove the facts, and active_goals(alias, active) returns the goals that switch the volk's active state. Registration and deregistration of volks in the volk registry (agents.volk_registry) lead to these goals.
At a glance
| Source | src/orchestrata_ultimate/governance/volk_facts.py |
| Lines of code | 104 |
| Classes | 0 |
| Functions | 4 |
| Imports (internal) | none |
| Imported by | orchestrata_ultimate.governance.prolog_client, orchestrata_ultimate.governance.prolog_gate |
| Tests that import it | tests/governance/test_volk_facts.py |
Class diagram
No classes; see Functions.
Dependency diagram
API
Constants
| Name | Type | Value |
|---|---|---|
OPERATIONAL_FACTS |
tuple[str, ...] |
('volk_exists', 'volk_active', 'volk_responsive', 'volk_within_resource_limits') |
BLOCKING_FACTS |
tuple[str, ...] |
('volk_blacklisted', 'volk_has_errors') |
Functions
| Function | Signature | Summary |
|---|---|---|
quote_atom |
quote_atom(alias: str) -> str |
Quote alias as a Prolog atom. |
assert_goals |
assert_goals(alias: str) -> tuple[str, ...] |
Goals that make alias satisfy volk_operational/1. |
retract_goals |
retract_goals(alias: str) -> tuple[str, ...] |
Goals that remove every volk_* fact for alias. |
active_goals |
active_goals(alias: str, active: bool) -> tuple[str, ...] |
Goals that set governance:volk_active/1 for alias. |
Source
"""The ``governance:volk_*`` facts ``may_execute/2`` needs, in one place.
``governance:may_execute/2`` clause 1 is::
may_execute(Agent, Action) :-
volk_operational(Agent),
\\+ agent_action_blocked(Agent, Action).
and ``volk_operational/1`` unfolds to ``volk_exists`` AND ``volk_active`` AND
``\\+ volk_blacklisted`` AND ``volk_healthy``, where ``volk_healthy`` is
``volk_responsive`` AND ``volk_within_resource_limits`` AND
``\\+ volk_has_errors``. Every one of those is a dynamic fact with no clauses
until something asserts it.
Nothing did. ``MultiagentPrologBridge`` has ``assert_volk_active`` and friends,
but they write into the ``multiagent:`` module while these rules read
``governance:`` — two namespaces that never meet. Clause 1 therefore always
failed, and the permissive clause that used to follow it allowed every agent
unconditionally (measured 2026-08-09: ``may_execute('attacker',
exfiltrate_secrets)`` was true against the real engine with all nine rule
files loaded).
TWO engines have to agree about which facts those are: ``PrologGate`` (the
orchestrator's stage gate, its own ``PrologEngine``) and
``GovernancePrologClient`` (the kernel/gateway path, a ``PrologBridge``).
Duplicating the list in both is how they start disagreeing about what
"operational" means, so the goal strings are built here and each engine only
supplies the execution.
"""
from __future__ import annotations
# The positive facts a volk must carry to satisfy volk_operational/1.
# volk_healthy/1's third leg is NEGATIVE (\+ volk_has_errors), so it appears in
# the retract list below rather than here.
OPERATIONAL_FACTS: tuple[str, ...] = (
"volk_exists",
"volk_active",
"volk_responsive",
"volk_within_resource_limits",
)
# The facts whose PRESENCE denies. Cleared on (re-)registration so a volk
# coming back after a suspension is not left half-blocked.
BLOCKING_FACTS: tuple[str, ...] = (
"volk_blacklisted",
"volk_has_errors",
)
def quote_atom(alias: str) -> str:
"""Quote *alias* as a Prolog atom.
Volk aliases contain a colon (``U:Cd``), which is Prolog's module-qualifier
operator — unquoted, ``U:Cd`` parses as a module reference and the fact
lands somewhere nobody reads. The inner quote escape matters for the same
reason it matters everywhere else: an alias is data, not syntax.
"""
return "'" + alias.replace("\\", "\\\\").replace("'", "\\'") + "'"
def assert_goals(alias: str) -> tuple[str, ...]:
"""Goals that make *alias* satisfy ``volk_operational/1``.
Each positive fact is retracted before it is asserted, so registering the
same alias twice leaves one clause rather than two — otherwise a single
``retractall`` on deregistration would look like it worked while a
duplicate kept the gate open.
"""
atom = quote_atom(alias)
goals: list[str] = []
for predicate in OPERATIONAL_FACTS:
goals.append(f"retractall(governance:{predicate}({atom}))")
goals.append(f"assertz(governance:{predicate}({atom}))")
for predicate in BLOCKING_FACTS:
goals.append(f"retractall(governance:{predicate}({atom}))")
return tuple(goals)
def retract_goals(alias: str) -> tuple[str, ...]:
"""Goals that remove every ``volk_*`` fact for *alias*.
A deregistered volk must stop being operational immediately; facts left
behind keep the gate open for an alias that is no longer there.
"""
atom = quote_atom(alias)
return tuple(
f"retractall(governance:{predicate}({atom}))"
for predicate in (*OPERATIONAL_FACTS, *BLOCKING_FACTS)
)
def active_goals(alias: str, active: bool) -> tuple[str, ...]:
"""Goals that set ``governance:volk_active/1`` for *alias*.
Registration is not liveness. A volk that misses its heartbeats goes
INACTIVE in the registry, and governance has to hear about it or the gate
keeps dispatching work to something that is not answering.
"""
atom = quote_atom(alias)
goals = [f"retractall(governance:volk_active({atom}))"]
if active:
goals.append(f"assertz(governance:volk_active({atom}))")
return tuple(goals)