orchestrata_ultimate.factory.projection.completeness

Reference › orchestrata_ultimate › factory › projection › completeness

completeness is the pre-run projection meta-check of ADR-0006 (SPEC-033 row B5): incomplete projection is a gate error, and in factory mode it fails closed (ADR-0002). A caller derives the RequiredSet with required_predicates from analyzer, then calls assert_projection_complete with that set and the collection of predicates it is about to project into Prolog. If any required extensional predicate is missing, the function raises IncompleteProjection, which carries the list of missing PredId values; it is never a warning or a silent pass. projection_manifest returns a JSON-ready snapshot of what was required, for gate provenance. The module delivers the contract only; adopting it at each gate is a separate reviewed change. The scripts.factory_projection CLI imports it, and tests/factory/test_projection_completeness.py tests it.

At a glance

Source src/orchestrata_ultimate/factory/projection/completeness.py
Lines of code 75
Classes 1
Functions 2
Imports (internal) orchestrata_ultimate.factory.projection.analyzer
Imported by scripts.factory_projection
Tests that import it tests/factory/test_projection_completeness.py

Class diagram

Class diagram orchestrata_ultimate.factory.projection.completeness

Dependency diagram

Dependency diagram orchestrata_ultimate.factory.projection.completeness

API

Classes

IncompleteProjection

Bases: Exception · Line 31

Raised when provided omits an extensional predicate a rulebase's rules consult -- the ADR-0006 fail-closed gate error.

Method Signature Summary
__init__ __init__(missing: list[PredId]) -> None

Functions

Function Signature Summary
assert_projection_complete assert_projection_complete(required: RequiredSet, provided: Collection[PredId]) -> None Raise :class:IncompleteProjection if any required.extensional predicate is absent from provided.
projection_manifest projection_manifest(required: RequiredSet) -> dict[str, list[str]] JSON-able snapshot of WHAT was required, for gate provenance (persisted alongside the verdict, per the brief -- "gates can persist WHAT was projected alongside the verdict").

Source

Permalink: https://gitlab.com/MSamy/orchestrata-ultimate-architecture/-/blob/a4cbc2bdf/src/orchestrata_ultimate/factory/projection/completeness.py

"""Projection-completeness pre-run meta-check (B5, ADR-0006).

ADR-0006's decision: "a meta-check asserts projection completeness before
the rulebase runs; incomplete projection is a gate error, and in factory
mode that fails closed (ADR-0002)". This module IS that meta-check.

The CALLER runs :func:`assert_projection_complete` before consulting the
rulebase, passing the derived :class:`~.analyzer.RequiredSet`
(:func:`~.analyzer.required_predicates`) and the collection of predicates it
is about to project into Prolog. A missing extensional predicate raises
:class:`IncompleteProjection` -- fail-closed, never a warning, never a
silent pass.

B5 wiring: per-gate adoption is a separate, reviewed change. This module
delivers the CONTRACT (call ``assert_projection_complete`` with your derived
required set + your projected fact collection before you `consult`/query);
it does not itself touch the existing per-gate assertion call sites (the
code that actually knows the fact store, per ADR-0005's ground-fact
discipline) -- see the package docstring's wiring note.
"""

from __future__ import annotations

from collections.abc import Collection
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from orchestrata_ultimate.factory.projection.analyzer import PredId, RequiredSet


class IncompleteProjection(Exception):
    """Raised when ``provided`` omits an extensional predicate a rulebase's
    rules consult -- the ADR-0006 fail-closed gate error.

    ``missing`` lists every absent ``PredId``, in the same order as the
    exception message, so a caller can report or retry against a specific
    predicate without re-parsing the message text.
    """

    def __init__(self, missing: list[PredId]) -> None:
        self.missing = missing
        named = ", ".join(str(p) for p in missing)
        super().__init__(
            f"projection incomplete -- missing extensional predicate(s): {named}"
        )


def assert_projection_complete(
    required: RequiredSet, provided: Collection[PredId]
) -> None:
    """Raise :class:`IncompleteProjection` if any ``required.extensional``
    predicate is absent from ``provided``.

    Intensional predicates (defined by clauses in the rulebase itself) are
    never demanded from ``provided`` -- they need no fact projection, only
    the rulebase's own source, which the caller already `consult`s.
    """
    provided_set = set(provided)
    missing = sorted(
        (pred for pred in required.extensional if pred not in provided_set),
        key=str,
    )
    if missing:
        raise IncompleteProjection(missing)


def projection_manifest(required: RequiredSet) -> dict[str, list[str]]:
    """JSON-able snapshot of WHAT was required, for gate provenance
    (persisted alongside the verdict, per the brief -- "gates can persist
    WHAT was projected alongside the verdict")."""
    return {
        "intensional": sorted(str(pred) for pred in required.intensional),
        "extensional": sorted(str(pred) for pred in required.extensional),
        "builtins": sorted(str(pred) for pred in required.builtins),
    }