Adds a typed legality check that catches a narrow class of incoherent
finite-predicate surfaces before they ship. Scope is deliberately
narrow:
- generate/articulation_legality.py:
- SlotKind enum {VERB, NON_VERB, UNKNOWN}
- ArticulationLegality enum {LEGAL, ILLEGAL_NON_VERB_FINITE_PREDICATE}
- classify_predicate_slot_kind() — token allowlists for known verbs
and known non-verb nouns
- validate_finite_predicate_legality() — fails on negated +
NON_VERB; fail-open on UNKNOWN to preserve canary behavior
- generate/templates.py:
- _inflect_predicate: copular-aware negation
("is X" -> "is not X" instead of the default "does not be X")
- render_step: invokes the legality validator; returns
"I cannot realize that proposition coherently yet." when an
illegal shape is detected
The check is upstream of register / anchor-lens transforms (presentation
+ substantive axes both downstream of the realizer); no interaction
with R6 / ADR-0073 layering.
Tests pin:
- NON_VERB + negated -> ILLEGAL_NON_VERB_FINITE_PREDICATE
- UNKNOWN + negated -> LEGAL (fail-open preserved)
- render_step returns the disclosure string when illegal detected
- render_step still produces the fall-through surface on UNKNOWN
Validation:
- Cognition eval byte-identical (100/100/91.7/100)
- 370 realizer / lens / register / pack / lane tests pass
- anchor-lens-tour + register-tour both green
101 lines
2.3 KiB
Python
101 lines
2.3 KiB
Python
"""Typed articulation legality checks at the realizer boundary.
|
|
|
|
C1.5 scope:
|
|
- Catch a narrow class of known-illegal finite-predicate shapes.
|
|
- Fail open when predicate slot kind is unknown.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
|
|
|
|
class SlotKind(Enum):
|
|
VERB = "verb"
|
|
NON_VERB = "non_verb"
|
|
UNKNOWN = "unknown"
|
|
|
|
|
|
class ArticulationLegality(Enum):
|
|
LEGAL = "legal"
|
|
ILLEGAL_NON_VERB_FINITE_PREDICATE = "illegal_non_verb_finite_predicate"
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class ArticulationLegalityVerdict:
|
|
legality: ArticulationLegality
|
|
predicate_kind: SlotKind
|
|
|
|
@property
|
|
def is_legal(self) -> bool:
|
|
return self.legality is ArticulationLegality.LEGAL
|
|
|
|
|
|
_KNOWN_NON_VERB_PREDICATES: frozenset[str] = frozenset(
|
|
{
|
|
"right",
|
|
"truth",
|
|
"light",
|
|
"knowledge",
|
|
"wisdom",
|
|
"evidence",
|
|
"thought",
|
|
"memory",
|
|
}
|
|
)
|
|
|
|
_KNOWN_VERB_PREDICATES: frozenset[str] = frozenset(
|
|
{
|
|
"is",
|
|
"are",
|
|
"has",
|
|
"have",
|
|
"belongs",
|
|
"supports",
|
|
"requires",
|
|
"grounds",
|
|
"reveals",
|
|
"defines",
|
|
"means",
|
|
"follows",
|
|
"precedes",
|
|
"causes",
|
|
"answers",
|
|
"verifies",
|
|
"evidences",
|
|
}
|
|
)
|
|
|
|
|
|
def classify_predicate_slot_kind(predicate_humanized: str) -> SlotKind:
|
|
token = predicate_humanized.strip().split(" ", 1)[0].lower()
|
|
if token in _KNOWN_VERB_PREDICATES:
|
|
return SlotKind.VERB
|
|
if token in _KNOWN_NON_VERB_PREDICATES:
|
|
return SlotKind.NON_VERB
|
|
return SlotKind.UNKNOWN
|
|
|
|
|
|
def validate_finite_predicate_legality(
|
|
*,
|
|
predicate_humanized: str,
|
|
negated: bool,
|
|
) -> ArticulationLegalityVerdict:
|
|
kind = classify_predicate_slot_kind(predicate_humanized)
|
|
if not negated:
|
|
return ArticulationLegalityVerdict(
|
|
legality=ArticulationLegality.LEGAL,
|
|
predicate_kind=kind,
|
|
)
|
|
if kind is SlotKind.NON_VERB:
|
|
return ArticulationLegalityVerdict(
|
|
legality=ArticulationLegality.ILLEGAL_NON_VERB_FINITE_PREDICATE,
|
|
predicate_kind=kind,
|
|
)
|
|
# Fail-open by design for UNKNOWN to preserve canary behavior.
|
|
return ArticulationLegalityVerdict(
|
|
legality=ArticulationLegality.LEGAL,
|
|
predicate_kind=kind,
|
|
)
|
|
|