from owl_sop_enforcement_gate import (
OntologyEditGate, GateMode, GateBlocked, GateDecision,
ShaclResult, reference_shacl_check, reference_phase_check,
is_substantive_verbatim, detect_mutation_type, is_ontology_path, main,
)OntologyEditGate(
*,
mode: GateMode | str | None = None, # default: $OSEG_GATE_MODE or "enforce"
shapes_graph_path: str | None = None, # SHACL shapes for ontology edits
shacl_check: Callable = reference_shacl_check,
phase_check: Callable = reference_phase_check,
owner_required_mutations: Iterable[str] = (),
mutation_detector: Callable = detect_mutation_type,
min_verbatim_chars: int = 50,
substance_check: Callable | None = None,
event_sink: Callable | None = None,
)| Parameter | Description |
|---|---|
mode |
"advisory" (warn+allow), "enforce" (block; default), "override" (logged bypass). |
shapes_graph_path |
SHACL shapes graph used to validate ontology (.ttl/.owl/.rdf) edits. Caller-supplied; no hard-coded path. Omit → SHACL degrades open. |
shacl_check |
Seam: (data_path, shapes_path) -> ShaclResult. Default degrades open. |
phase_check |
Seam: (change_set_id, mutation_type) -> (ok, missing). Default reports all complete. |
owner_required_mutations |
Mutation types that also require a responsible_owner. |
mutation_detector |
(file_path) -> mutation_type | None. Default: .ttl/.owl/.rdf → "new_class", .json → "config_edit". |
min_verbatim_chars |
Non-whitespace-char floor for the verbatim rationale (default 50). |
substance_check |
Override the inline substance check with (text) -> bool. |
event_sink |
(kind, detail) -> None advisor sink. Default: best-effort probe, else no-op. |
evaluate(file_path, *, verbatim_response=None, responsible_owner=None, change_set_id="default", mutation_type=None) -> GateDecision
A pure verdict — never raises, logs, or exits. Detects the mutation type (an explicit mutation_type wins over path heuristics), runs the four findings in order, and returns a GateDecision. A non-gated path returns GateDecision(allowed=True, mutation_type=None).
enforce(file_path, *, verbatim_response=None, responsible_owner=None, change_set_id="default", mutation_type=None, override=None, override_reason=None) -> GateDecision
Calls evaluate, then acts on the mode:
| Mode | On a blocking finding |
|---|---|
advisory |
prints an ADVISORY line to stderr, returns the decision (allows) |
enforce |
raises GateBlocked(decision) |
override |
prints an OVERRIDE line to stderr, returns the decision (allows) |
A per-call override=True (or env OSEG_OVERRIDE=1) forces the override path without changing the gate's mode; the reason (override_reason or $OSEG_OVERRIDE_REASON) is always logged. When an ontology edit's SHACL check returned "skipped"/"error", enforce prints a "degrading open" note and allows. Returns the GateDecision whenever it does not raise.
Frozen dataclass returned by evaluate:
| Field | Meaning |
|---|---|
allowed: bool |
True if no blocking finding (reflects findings; an override still allows). |
mutation_type: str | None |
Detected type, or None for a non-gated path. |
reasons: list[str] |
One line per blocking finding; empty when allowed. |
missing_phases: list |
Incomplete prerequisite phases from phase_check. |
shacl_status: str | None |
"ok"/"violations"/"skipped"/"error", or None if no SHACL applied. |
shacl_violation_count: int |
Violation count when shacl_status == "violations". |
overridable: bool |
Whether a documented override may bypass the findings. |
.to_dict() returns a JSON-friendly dict.
enum.Enum of ADVISORY / ENFORCE / OVERRIDE. GateMode.coerce(value) maps a string (case-insensitive) to a mode, defaulting to ENFORCE.
Raised by enforce in enforce mode on a blocking finding. Carries .decision (the GateDecision); str(exc) joins the reasons.
ShaclResult(status="skipped", violation_count=0, detail="")—.conformsisstatus == "ok". The shape theshacl_checkseam returns.reference_shacl_check(data_path, shapes_path=None) -> ShaclResult— degrade-open reference: lazily importspyshacl(so importing the package never requires it); returns"skipped"whenpyshaclis absent or no shapes are supplied.reference_phase_check(change_set_id, mutation_type) -> (True, [])— degrade-open reference: reports all prerequisites complete.is_substantive_verbatim(text, *, min_chars=50) -> bool— the inline substance floor: ≥min_charsnon-whitespace chars and at least one alphanumeric.detect_mutation_type(file_path) -> str | None/is_ontology_path(file_path) -> bool— the default path heuristics.
Pre-commit / pre-tool-use hook entry point (console script owl-sop-gate). Reads the edit envelope from JSON on $OSEG_TOOL_INPUT or argv[0], builds a gate from OSEG_* env vars, enforces, and returns 0 (allowed) or 2 (blocked in enforce mode). Never crashes on a malformed envelope.
Envelope keys: file_path (required), verbatim_response, responsible_owner, change_set_id, mutation_type.
try_emit_event(kind, detail) -> bool— best-effort advisor-event emit;Falseif no sink importable. Never raises.try_substance_check(text) -> bool | None— best-effort external substance linter;Noneif none importable (the gate then usesis_substantive_verbatim). Never raises.